You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2013/10/21 10:12:08 UTC
svn commit: r1534058 - in
/sling/trunk/bundles/extensions/webconsolesecurityprovider: ./
src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/
src/main/resources/
Author: cziegeler
Date: Mon Oct 21 08:12:07 2013
New Revision: 1534058
URL: http://svn.apache.org/r1534058
Log:
SLING-3193 : Implement WebConsoleSecurityProvider2 for integration with Sling Authenticator
Added:
sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/AbstractWebConsoleSecurityProvider.java (with props)
sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/Activator.java (with props)
sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/ServicesListener.java (with props)
sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider2.java (with props)
Removed:
sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/resources/
Modified:
sling/trunk/bundles/extensions/webconsolesecurityprovider/pom.xml
sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider.java
Modified: sling/trunk/bundles/extensions/webconsolesecurityprovider/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/webconsolesecurityprovider/pom.xml?rev=1534058&r1=1534057&r2=1534058&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/webconsolesecurityprovider/pom.xml (original)
+++ sling/trunk/bundles/extensions/webconsolesecurityprovider/pom.xml Mon Oct 21 08:12:07 2013
@@ -56,6 +56,13 @@
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>
+ org.apache.sling.extensions.webconsolesecurityprovider.internal.Activator
+ </Bundle-Activator>
+ </instructions>
+ </configuration>
</plugin>
</plugins>
</build>
@@ -74,19 +81,43 @@
<dependencies>
<dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.webconsole</artifactId>
- <version>3.1.0</version>
+ <version>4.2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.api</artifactId>
+ <version>2.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.auth.core</artifactId>
+ <version>1.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-api</artifactId>
- <version>1.5.0</version>
+ <version>2.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
Added: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/AbstractWebConsoleSecurityProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/AbstractWebConsoleSecurityProvider.java?rev=1534058&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/AbstractWebConsoleSecurityProvider.java (added)
+++ sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/AbstractWebConsoleSecurityProvider.java Mon Oct 21 08:12:07 2013
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.extensions.webconsolesecurityprovider.internal;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.felix.webconsole.WebConsoleSecurityProvider;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the common base class for the two provider implementations.
+ * It handles the configuration of the service.
+ */
+public abstract class AbstractWebConsoleSecurityProvider
+ implements WebConsoleSecurityProvider, ManagedService {
+
+ // name of the property providing list of authorized users
+ private static final String PROP_USERS = "users";
+
+ // default user being authorized
+ public static final String PROP_GROUPS_DEFAULT_USER = "admin";
+
+ // name of the property providing list of groups whose members are
+ // authorized
+ private static final String PROP_GROUPS = "groups";
+
+ /** default logger */
+ protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+ protected Set<String> users = Collections.singleton(PROP_GROUPS_DEFAULT_USER);
+
+ protected Set<String> groups = Collections.emptySet();
+
+ /**
+ * Handle configuration
+ * @see org.osgi.service.cm.ManagedService#updated(java.util.Dictionary)
+ */
+ public void updated(final Dictionary properties)
+ throws ConfigurationException {
+ this.users = toSet(properties == null ? null : properties.get(PROP_USERS), PROP_GROUPS_DEFAULT_USER);
+ this.groups = toSet(properties == null ? null : properties.get(PROP_GROUPS), null);
+ }
+
+ private Set<String> toSet(final Object configObj, final String defaultUser) {
+ final Set<String> groups = new HashSet<String>();
+ if (configObj instanceof String) {
+ groups.add((String) configObj);
+ } else if (configObj instanceof Collection<?>) {
+ for (Object obj : ((Collection<?>) configObj)) {
+ if (obj instanceof String) {
+ groups.add((String) obj);
+ }
+ }
+ } else if (configObj instanceof String[]) {
+ for (String string : ((String[]) configObj)) {
+ if (string != null) {
+ groups.add(string);
+ }
+ }
+ } else if (configObj == null && defaultUser != null) {
+ groups.add(defaultUser);
+ }
+ return groups;
+ }
+}
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/AbstractWebConsoleSecurityProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/AbstractWebConsoleSecurityProvider.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/AbstractWebConsoleSecurityProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/Activator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/Activator.java?rev=1534058&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/Activator.java (added)
+++ sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/Activator.java Mon Oct 21 08:12:07 2013
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.extensions.webconsolesecurityprovider.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private ServicesListener listener;
+
+ /**
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(final BundleContext context) throws Exception {
+ listener = new ServicesListener(context);
+ }
+
+ /**
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(final BundleContext context) throws Exception {
+ if ( listener != null ) {
+ listener.deactivate();
+ listener = null;
+ }
+ }
+}
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/Activator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/Activator.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/Activator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/ServicesListener.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/ServicesListener.java?rev=1534058&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/ServicesListener.java (added)
+++ sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/ServicesListener.java Mon Oct 21 08:12:07 2013
@@ -0,0 +1,275 @@
+package org.apache.sling.extensions.webconsolesecurityprovider.internal;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import javax.jcr.Repository;
+
+import org.apache.felix.webconsole.WebConsoleSecurityProvider;
+import org.apache.sling.auth.core.AuthenticationSupport;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ManagedService;
+
+/**
+ * The <code>ServicesListener</code> listens for the required services
+ * and registers the security provider when required services are available
+ */
+public class ServicesListener {
+
+ /** The bundle context. */
+ private final BundleContext bundleContext;
+
+ /** The listener for the repository. */
+ private final Listener repositoryListener;
+
+ /** The listener for the authentication support. */
+ private final Listener authSupportListener;
+
+ private final SlingWebConsoleSecurityProvider provider = new SlingWebConsoleSecurityProvider();
+
+ private final SlingWebConsoleSecurityProvider2 provider2 = new SlingWebConsoleSecurityProvider2();
+
+ private enum State {
+ NONE,
+ PROVIDER,
+ PROVIDER2
+ };
+
+ /** State */
+ private volatile State registrationState = State.NONE;
+
+ /** The registration for the provider */
+ private ServiceRegistration providerReg;
+
+ /** The registration for the provider2 */
+ private ServiceRegistration provider2Reg;
+
+
+ /**
+ * Start listeners
+ */
+ public ServicesListener(final BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ this.authSupportListener = new Listener(AuthenticationSupport.class.getName());
+ this.repositoryListener = new Listener(Repository.class.getName());
+ this.authSupportListener.start();
+ this.repositoryListener.start();
+ }
+
+ /**
+ * Notify of service changes from the listeners.
+ */
+ public synchronized void notifyChange() {
+ // check if all services are available
+ final AuthenticationSupport authSupport = (AuthenticationSupport)this.authSupportListener.getService();
+ final Repository repository = (Repository)this.repositoryListener.getService();
+ if ( registrationState == State.NONE ) {
+ if ( authSupport != null ) {
+ registerProvider2(authSupport);
+ } else if ( repository != null ) {
+ registerProvider(repository);
+ }
+ } else if ( registrationState == State.PROVIDER ) {
+ if ( authSupport != null ) {
+ registerProvider2(authSupport);
+ unregisterProvider();
+ } else if ( repository == null ) {
+ unregisterProvider();
+ this.registrationState = State.NONE;
+ } else {
+ this.provider.setService(repository);
+ }
+ } else {
+ if ( authSupport == null ) {
+ if ( repository != null ) {
+ registerProvider(repository);
+ } else {
+ this.registrationState = State.NONE;
+ }
+ unregisterProvider2();
+ } else {
+ this.provider2.setService(authSupport);
+ }
+ }
+ }
+
+ private void unregisterProvider2() {
+ if ( this.provider2Reg != null ) {
+ this.provider2Reg.unregister();
+ this.provider2Reg = null;
+ }
+ this.provider2.setService(null);
+ }
+
+ private void unregisterProvider() {
+ if ( this.providerReg != null ) {
+ this.providerReg.unregister();
+ this.providerReg = null;
+ }
+ this.provider.setService(null);
+ }
+
+ private void registerProvider2(final AuthenticationSupport authSupport) {
+ this.provider2.setService(authSupport);
+ final Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(Constants.SERVICE_PID, SlingWebConsoleSecurityProvider.class.getName());
+ props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Web Console Security Provider 2");
+ props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+ this.provider2Reg = this.bundleContext.registerService(
+ new String[] {ManagedService.class.getName(), WebConsoleSecurityProvider.class.getName()}, this.provider2, props);
+ this.registrationState = State.PROVIDER2;
+ }
+
+ private void registerProvider(final Repository repository) {
+ this.provider.setService(repository);
+ final Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(Constants.SERVICE_PID, SlingWebConsoleSecurityProvider.class.getName());
+ props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Web Console Security Provider");
+ props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+ this.providerReg = this.bundleContext.registerService(
+ new String[] {ManagedService.class.getName(), WebConsoleSecurityProvider.class.getName()}, this.provider, props);
+ this.registrationState = State.PROVIDER;
+ }
+
+ /**
+ * Deactivate this listener.
+ */
+ public void deactivate() {
+ this.repositoryListener.deactivate();
+ this.authSupportListener.deactivate();
+ this.unregisterProvider();
+ this.unregisterProvider2();
+ }
+
+ /**
+ * Helper class listening for service events for a defined service.
+ */
+ protected final class Listener implements ServiceListener {
+
+ /** The name of the service. */
+ private final String serviceName;
+
+ /** The service reference. */
+ private volatile ServiceReference reference;
+
+ /** The service. */
+ private volatile Object service;
+
+ /**
+ * Constructor
+ */
+ public Listener(final String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ /**
+ * Start the listener.
+ * First register a service listener and then check for the service.
+ */
+ public void start() {
+ try {
+ bundleContext.addServiceListener(this, "("
+ + Constants.OBJECTCLASS + "=" + serviceName + ")");
+ } catch (final InvalidSyntaxException ise) {
+ // this should really never happen
+ throw new RuntimeException("Unexpected exception occured.", ise);
+ }
+ final ServiceReference ref = bundleContext.getServiceReference(serviceName);
+ if ( ref != null ) {
+ this.retainService(ref);
+ }
+ }
+
+ /**
+ * Unregister the listener.
+ */
+ public void deactivate() {
+ bundleContext.removeServiceListener(this);
+ }
+
+ /**
+ * Return the service (if available)
+ */
+ public synchronized Object getService() {
+ return this.service;
+ }
+
+ /**
+ * Try to get the service and notify the change.
+ */
+ private synchronized void retainService(final ServiceReference ref) {
+ boolean hadService = this.service != null;
+ boolean getService = this.reference == null;
+ if ( !getService ) {
+ final int result = this.reference.compareTo(ref);
+ if ( result < 0 ) {
+ bundleContext.ungetService(this.reference);
+ this.service = null;
+ getService = true;
+ }
+ }
+ if ( getService ) {
+ this.reference = ref;
+ this.service = bundleContext.getService(this.reference);
+ if ( this.service == null ) {
+ this.reference = null;
+ } else {
+ notifyChange();
+ }
+ }
+ if ( hadService && this.service == null ) {
+ notifyChange();
+ }
+ }
+
+ /**
+ * Try to release the service and notify the change.
+ */
+ private synchronized void releaseService(final ServiceReference ref) {
+ if ( this.reference != null && this.reference.compareTo(ref) == 0) {
+ this.service = null;
+ bundleContext.ungetService(this.reference);
+ this.reference = null;
+ notifyChange();
+ }
+ }
+
+ /**
+ * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+ */
+ public void serviceChanged(final ServiceEvent event) {
+ if (event.getType() == ServiceEvent.REGISTERED) {
+ this.retainService(event.getServiceReference());
+ } else if ( event.getType() == ServiceEvent.UNREGISTERING ) {
+ this.releaseService(event.getServiceReference());
+ } else if ( event.getType() == ServiceEvent.MODIFIED ) {
+ notifyChange();
+ }
+ }
+ }
+}
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/ServicesListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/ServicesListener.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/ServicesListener.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider.java?rev=1534058&r1=1534057&r2=1534058&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider.java (original)
+++ sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider.java Mon Oct 21 08:12:07 2013
@@ -18,33 +18,22 @@
*/
package org.apache.sling.extensions.webconsolesecurityprovider.internal;
-import java.util.Collection;
-import java.util.HashSet;
import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
import javax.jcr.Credentials;
import javax.jcr.LoginException;
import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
-import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.felix.webconsole.WebConsoleSecurityProvider;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* The <code>SlingWebConsoleSecurityProvider</code> is security provider for the
@@ -58,42 +47,35 @@ import org.slf4j.LoggerFactory;
* only registered as a security provider service once such a JCR Repository is
* available.
*/
-@Component(specVersion = "1.1", metatype = true)
-@Service(WebConsoleSecurityProvider.class)
-public class SlingWebConsoleSecurityProvider implements
- WebConsoleSecurityProvider {
+@Component(ds=false, metatype=true,
+ label="Apache Sling Web Console Security Provider",
+ description="Configuration for the security provider used to verfiy user " +
+ "credentials and grant access to the Apache Felix Web Console " +
+ "based on registered JCR Repository users.")
+@Properties({
+ @Property(name = "users", value=AbstractWebConsoleSecurityProvider.PROP_GROUPS_DEFAULT_USER, cardinality=20,
+ label="User Names",
+ description="Names of users granted full access to the Apache Felix " +
+ "Web Console. By default this lists the \"admin\" user. A maximum of 20 users" +
+ " may be configured. Administrators are encouraged to create a group whose" +
+ " members are to be granted access to Web Console instead of allowing access" +
+ " to individual users."),
+ @Property(name = "groups", cardinality=20,
+ label="Group Names",
+ description="Names of groups whose members are granted full access to the Apache Felix " +
+ "Web Console. The default lists no groups. Administrators are encouraged to " +
+ "create a group whose members are to be granted access to the Web Console." +
+ " A maximum of 20 groups may be configured. Using groups to control" +
+ " access requires a Jackrabbit based repository.")
+})
+public class SlingWebConsoleSecurityProvider extends AbstractWebConsoleSecurityProvider {
- // name of the property providing list of authorized users
- private static final String PROP_USERS = "users";
-
- // default user being authorized
- private static final String PROP_GROUPS_DEFAULT_USER = "admin";
-
- // name of the property providing list of groups whose members are
- // authorized
- private static final String PROP_GROUPS = "groups";
-
- /** default log */
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- @Reference
private Repository repository;
- @Property(name = PROP_USERS, cardinality = 20, value = PROP_GROUPS_DEFAULT_USER)
- private Set<String> users;
-
- @Property(name = PROP_GROUPS, cardinality = 20)
- private Set<String> groups;
-
- // ---------- SCR integration
-
- @SuppressWarnings("unused")
- @Activate
- @Modified
- private void configure(Map<String, Object> config) {
- this.users = toSet(config.get(PROP_USERS));
- this.groups = toSet(config.get(PROP_GROUPS));
+ public void setService(final Repository repo) {
+ this.repository = repo;
}
+ // ---------- SCR integration
/**
* Authenticates and authorizes the user identified by the user name and
@@ -148,27 +130,27 @@ public class SlingWebConsoleSecurityProv
}
}
- log.info(
- "authenticate: User {} is granted Web Console access",
+ logger.debug(
+ "authenticate: User {} is denied Web Console access",
userName);
} else {
- log.error(
+ logger.error(
"authenticate: Expected user ID {} to refer to a user",
userId);
}
} else {
- log.info(
+ logger.info(
"authenticate: Jackrabbit Session required to grant access to the Web Console for {}; got {}",
userName, session.getClass());
}
- } catch (LoginException re) {
- log.info(
+ } catch (final LoginException re) {
+ logger.info(
"authenticate: User "
+ userName
+ " failed to authenticate with the repository for Web Console access",
re);
- } catch (Exception re) {
- log.info("authenticate: Generic problem trying grant User "
+ } catch (final Exception re) {
+ logger.info("authenticate: Generic problem trying grant User "
+ userName + " access to the Web Console", re);
} finally {
if (session != null) {
@@ -185,27 +167,7 @@ public class SlingWebConsoleSecurityProv
* authorized groups are granted access for all roles in the Web Console.
*/
public boolean authorize(Object user, String role) {
- log.info("authorize: Grant user {} access for role {}", user, role);
+ logger.debug("authorize: Grant user {} access for role {}", user, role);
return true;
}
-
- private Set<String> toSet(final Object configObj) {
- final HashSet<String> groups = new HashSet<String>();
- if (configObj instanceof String) {
- groups.add((String) configObj);
- } else if (configObj instanceof Collection<?>) {
- for (Object obj : ((Collection<?>) configObj)) {
- if (obj instanceof String) {
- groups.add((String) obj);
- }
- }
- } else if (configObj instanceof String[]) {
- for (String string : ((String[]) configObj)) {
- if (string != null) {
- groups.add(string);
- }
- }
- }
- return groups;
- }
}
Added: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider2.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider2.java?rev=1534058&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider2.java (added)
+++ sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider2.java Mon Oct 21 08:12:07 2013
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.extensions.webconsolesecurityprovider.internal;
+
+import java.util.Iterator;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.webconsole.WebConsoleSecurityProvider2;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.auth.core.AuthenticationSupport;
+
+/**
+ * The <code>SlingWebConsoleSecurityProvider</code> is security provider for the
+ * Apache Felix Web Console which validates the user name and password by loging
+ * into the repository and the checking whether the user is allowed access.
+ * Access granted by the {@link #authenticate(String, String)} method applies to
+ * all of the Web Console since the {@link #authorize(Object, String)} method
+ * always returns <code>true</code>.
+ * <p>
+ * This security provider requires a JCR Repository to operate. Therefore it is
+ * only registered as a security provider service once such a JCR Repository is
+ * available.
+ */
+public class SlingWebConsoleSecurityProvider2
+ extends AbstractWebConsoleSecurityProvider
+ implements WebConsoleSecurityProvider2 {
+
+ private AuthenticationSupport authenticator;
+
+ public void setService(final AuthenticationSupport support) {
+ this.authenticator = support;
+ }
+
+ private void invokeAuthenticator(final HttpServletRequest request, final HttpServletResponse response) {
+ final AuthenticationSupport localAuthenticator = this.authenticator;
+ if (localAuthenticator != null) {
+ localAuthenticator.handleSecurity(request, response);
+ }
+ }
+
+ /**
+ * @see org.apache.felix.webconsole.WebConsoleSecurityProvider2#authenticate(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ public boolean authenticate(final HttpServletRequest request,
+ final HttpServletResponse response) {
+ invokeAuthenticator(request, response);
+ // get ResourceResolver (set by AuthenticationSupport)
+ Object resolverObject = request.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);
+ final ResourceResolver resolver = (resolverObject instanceof ResourceResolver)
+ ? (ResourceResolver) resolverObject
+ : null;
+ if ( resolver != null ) {
+ final Session session = resolver.adaptTo(Session.class);
+ if ( session != null ) {
+ try {
+ final User u = this.authenticate(session);
+ if ( u != null ) {
+ request.setAttribute(USER_ATTRIBUTE, u);
+ return true;
+ }
+ return false;
+ } catch (final Exception re) {
+ logger.info("authenticate: Generic problem trying grant User "
+ + " access to the Web Console", re);
+ }
+ }
+ }
+ return false;
+ }
+
+ public User authenticate(String userName, String password) {
+ return null; // this method is never invoked
+ }
+
+ private User authenticate(final Session session) throws RepositoryException {
+ String userId = session.getUserID();
+ if (session instanceof JackrabbitSession) {
+ UserManager umgr = ((JackrabbitSession) session).getUserManager();
+ Authorizable a = umgr.getAuthorizable(userId);
+ if (a instanceof User) {
+
+ // check users
+ if (users.contains(userId)) {
+ return (User)a;
+ }
+
+ // check groups
+ @SuppressWarnings("unchecked")
+ Iterator<Group> gi = a.memberOf();
+ while (gi.hasNext()) {
+ if (groups.contains(gi.next().getID())) {
+ return (User)a;
+ }
+ }
+
+ logger.info(
+ "authenticate: User {} is denied Web Console access",
+ userId);
+ } else {
+ logger.error(
+ "authenticate: Expected user ID {} to refer to a user",
+ userId);
+ }
+ } else {
+ logger.info(
+ "authenticate: Jackrabbit Session required to grant access to the Web Console for {}; got {}",
+ userId, session.getClass());
+ }
+ return null;
+ }
+
+ /**
+ * All users authenticated with the repository and being a member of the
+ * authorized groups are granted access for all roles in the Web Console.
+ */
+ public boolean authorize(Object user, String role) {
+ logger.debug("authorize: Grant user {} access for role {}", user, role);
+ return true;
+ }
+}
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider2.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider2.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/extensions/webconsolesecurityprovider/src/main/java/org/apache/sling/extensions/webconsolesecurityprovider/internal/SlingWebConsoleSecurityProvider2.java
------------------------------------------------------------------------------
svn:mime-type = text/plain