You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2012/10/16 09:04:24 UTC
svn commit: r1398676 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/security/
main/java/org/apache/jackrabbit/oak/security/authentication/
main/java/org/apache/jackrabbit/oak/security/authentication/token/
main/java/org/ap...
Author: angela
Date: Tue Oct 16 07:04:23 2012
New Revision: 1398676
URL: http://svn.apache.org/viewvc?rev=1398676&view=rev
Log:
OAK-91 - Implement Authentication Support (WIP)
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/UserAuthentication.java
- copied, changed from r1397539, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModuleTest.java
Removed:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/ConfigurationImpl.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/CallbackHandlerImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/LoginModuleImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModule.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/RepositoryCallback.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/SecurityProviderCallback.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java?rev=1398676&r1=1398675&r2=1398676&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java Tue Oct 16 07:04:23 2012
@@ -16,15 +16,17 @@
*/
package org.apache.jackrabbit.oak.security;
+import java.util.Collections;
import javax.annotation.Nonnull;
import javax.jcr.Session;
+import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
-import org.apache.jackrabbit.oak.security.authentication.ConfigurationImpl;
import org.apache.jackrabbit.oak.security.authentication.LoginContextProviderImpl;
+import org.apache.jackrabbit.oak.security.authentication.LoginModuleImpl;
import org.apache.jackrabbit.oak.security.authentication.token.TokenProviderImpl;
import org.apache.jackrabbit.oak.security.authorization.AccessControlProviderImpl;
import org.apache.jackrabbit.oak.security.principal.PrincipalManagerImpl;
@@ -41,14 +43,24 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.user.UserContext;
import org.apache.jackrabbit.oak.spi.security.user.UserProvider;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class SecurityProviderImpl implements SecurityProvider {
+ private static final Logger log = LoggerFactory.getLogger(SecurityProviderImpl.class);
+
@Nonnull
@Override
public LoginContextProvider getLoginContextProvider(NodeStore nodeStore) {
- // TODO: use configurable authentication config
- Configuration configuration = new ConfigurationImpl();
+ Configuration configuration;
+ try {
+ configuration = Configuration.getConfiguration();
+ } catch (SecurityException e) {
+ log.warn("Failed to read login configuration: using default.", e);
+ configuration = new OakConfiguration();
+ Configuration.setConfiguration(configuration);
+ }
return new LoginContextProviderImpl(configuration, nodeStore, this);
}
@@ -91,4 +103,17 @@ public class SecurityProviderImpl implem
}
};
}
+
+ //--------------------------------------------------------------------------
+ private class OakConfiguration extends Configuration {
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
+ AppConfigurationEntry entry = new AppConfigurationEntry(
+ LoginModuleImpl.class.getName(),
+ AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+ Collections.<String, Object>emptyMap());
+ return new AppConfigurationEntry[] {entry};
+ }
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/CallbackHandlerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/CallbackHandlerImpl.java?rev=1398676&r1=1398675&r2=1398676&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/CallbackHandlerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/CallbackHandlerImpl.java Tue Oct 16 07:04:23 2012
@@ -27,12 +27,9 @@ import javax.security.auth.callback.Unsu
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
import org.apache.jackrabbit.oak.spi.security.authentication.callback.CredentialsCallback;
-import org.apache.jackrabbit.oak.spi.security.authentication.callback.PrincipalProviderCallback;
import org.apache.jackrabbit.oak.spi.security.authentication.callback.RepositoryCallback;
import org.apache.jackrabbit.oak.spi.security.authentication.callback.SecurityProviderCallback;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Default implementation of the {@link CallbackHandler} interface. It currently
@@ -42,16 +39,12 @@ import org.slf4j.LoggerFactory;
* <li>{@link CredentialsCallback}</li>
* <li>{@link NameCallback}</li>
* <li>{@link PasswordCallback}</li>
- * <li>{@link PrincipalProviderCallback}</li>
+ * <li>{@link SecurityProviderCallback}</li>
+ * <li>{@link RepositoryCallback}</li>
* </ul>
*/
public class CallbackHandlerImpl implements CallbackHandler {
- /**
- * logger instance
- */
- private static final Logger log = LoggerFactory.getLogger(CallbackHandlerImpl.class);
-
private final Credentials credentials;
private final String workspaceName;
private final NodeStore nodeStore;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/LoginModuleImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/LoginModuleImpl.java?rev=1398676&r1=1398675&r2=1398676&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/LoginModuleImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/LoginModuleImpl.java Tue Oct 16 07:04:23 2012
@@ -28,7 +28,6 @@ import javax.jcr.GuestCredentials;
import javax.jcr.SimpleCredentials;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
@@ -104,10 +103,6 @@ public final class LoginModuleImpl exten
private String userId;
//--------------------------------------------------------< LoginModule >---
- @Override
- public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
- super.initialize(subject, callbackHandler, sharedState, options);
- }
@Override
public boolean login() throws LoginException {
@@ -119,7 +114,7 @@ public final class LoginModuleImpl exten
return false;
}
- Authentication authentication = new AuthenticationImpl(userId, getUserProvider(), getPrincipalProvider());
+ Authentication authentication = new UserAuthentication(userId, getUserProvider(), getPrincipalProvider());
boolean success = authentication.authenticate(credentials);
if (success) {
principals = getPrincipals(userId);
Copied: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/UserAuthentication.java (from r1397539, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/UserAuthentication.java?p2=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/UserAuthentication.java&p1=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java&r1=1397539&r2=1398676&rev=1398676&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/UserAuthentication.java Tue Oct 16 07:04:23 2012
@@ -38,15 +38,15 @@ import org.slf4j.LoggerFactory;
/**
* AuthenticationImpl...
*/
-public class AuthenticationImpl implements Authentication {
+public class UserAuthentication implements Authentication {
- private static final Logger log = LoggerFactory.getLogger(AuthenticationImpl.class);
+ private static final Logger log = LoggerFactory.getLogger(UserAuthentication.class);
private final String userId;
private final UserProvider userProvider;
private final PrincipalProvider principalProvider;
- public AuthenticationImpl(String userId, UserProvider userProvider, PrincipalProvider principalProvider) {
+ public UserAuthentication(String userId, UserProvider userProvider, PrincipalProvider principalProvider) {
this.userId = userId;
this.userProvider = userProvider;
this.principalProvider = principalProvider;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java?rev=1398676&r1=1398675&r2=1398676&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java Tue Oct 16 07:04:23 2012
@@ -98,6 +98,7 @@ public final class TokenLoginModule exte
// the login attempt on this module did not succeed: clear state
// and check if another successful login asks for a new token to be created.
clearState();
+
if (tokenProvider != null && sharedState.containsKey(SHARED_KEY_CREDENTIALS)) {
Credentials shared = getSharedCredentials();
if (shared != null && tokenProvider.doCreateToken(shared)) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModule.java?rev=1398676&r1=1398675&r2=1398676&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModule.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModule.java Tue Oct 16 07:04:23 2012
@@ -39,6 +39,7 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.authentication.callback.PrincipalProviderCallback;
import org.apache.jackrabbit.oak.spi.security.authentication.callback.RepositoryCallback;
import org.apache.jackrabbit.oak.spi.security.authentication.callback.SecurityProviderCallback;
+import org.apache.jackrabbit.oak.spi.security.authentication.callback.UserProviderCallback;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
import org.apache.jackrabbit.oak.spi.security.user.UserProvider;
import org.slf4j.Logger;
@@ -53,71 +54,80 @@ import org.slf4j.LoggerFactory;
* This base class provides a simple implementation for the following methods
* of the {@code LoginModule} interface:
*
- * <h3>{@link LoginModule#initialize(Subject, CallbackHandler, Map, Map) Initialize}</h3>
- * Initialization of this abstract module sets the following protected instance
- * fields:
* <ul>
- * <li>subject: The subject to be authenticated,</li>
- * <li>callbackHandler: The callback handler passed to the login module,</li>
- * <li>shareState: The map used to share state information with other login
- * modules,</li>
- * <li>options: The configuration options of this login module as specified
- * in the {@link javax.security.auth.login.Configuration}.</li>
+ * <li>{@link LoginModule#initialize(Subject, CallbackHandler, Map, Map) Initialize}:
+ * Initialization of this abstract module sets the following protected instance
+ * fields:
+ * <ul>
+ * <li>subject: The subject to be authenticated,</li>
+ * <li>callbackHandler: The callback handler passed to the login module,</li>
+ * <li>shareState: The map used to share state information with other login modules,</li>
+ * <li>options: The configuration options of this login module as specified
+ * in the {@link javax.security.auth.login.Configuration}.</li>
+ * </ul>
+ * </li>
+ * <li>{@link LoginModule#logout() Logout}:
+ * If the authenticated subject is not empty this logout implementation
+ * attempts to clear both principals and public credentials and returns
+ * {@code true}.</li>
+ * <li>{@link LoginModule#abort() Abort}: Clears the state of this login
+ * module by setting all private instance variables created in phase 1 or 2
+ * to {@code null}. Subclasses are in charge of releasing their own state
+ * information by either overriding {@link #clearState()}.</li>
* </ul>
*
- * <h3>{@link LoginModule#logout() Logout}</h3>
- * If the authenticated subject is not empty this logout implementation attempts
- * to clear both principals and public credentials and returns {@code true}.
- *
- * <h3>{@link LoginModule#abort() Abort}</h3>
- * Clears the state of this login module by setting all private instance
- * variables created in phase 1 or 2 to {@code null}. Subclasses are in charge of
- * releasing their own state information by either overriding {@link #clearState()}.
- *
* <h2>Utility Methods</h2>
* The following methods are provided in addition:
*
- * <h3>{@link #clearState()}</h3>
- * Clears all private state information that has be created during login. This
- * method in called in {@link #abort()} and subclasses are expected to override
- * this method.
- *
- * <h3>{@link #getSupportedCredentials()}</h3>
- * Abstract method used by {@link #getCredentials()} that reveals which credential
- * implementations are supported by the {@code LoginModule}.
- *
- * <h3>{@link #getCredentials()}</h3>
- * Tries to retrieve valid (supported) Credentials in the following order:
- * <ol>
+ * <ul>
+ * <li>{@link #clearState()}: Clears all private state information that has
+ * be created during login. This method in called in {@link #abort()} and
+ * subclasses are expected to override this method.</li>
+ *
+ * <li>{@link #getSupportedCredentials()}: Abstract method used by
+ * {@link #getCredentials()} that reveals which credential implementations
+ * are supported by the {@code LoginModule}.</li>
+ *
+ * <li>{@link #getCredentials()}: Tries to retrieve valid (supported)
+ * Credentials in the following order:
+ * <ol>
* <li>using a {@link CredentialsCallback},</li>
* <li>looking for a {@link #SHARED_KEY_CREDENTIALS} entry in the shared
* state (see also {@link #getSharedCredentials()} and finally by</li>
* <li>searching for valid credentials in the subject.</li>
- * </ol>
- *
- * <h3>{@link #getSharedCredentials()}</h3>
- * This method returns any credentials passed to the login module with the
- * share state. The key to share credentials with a another module extending from
- * this base class is {@link #SHARED_KEY_CREDENTIALS}.
- *
- * <h3>{@link #getSharedLoginName()}</h3>
- * If the shared state contains an entry for {@link #SHARED_KEY_LOGIN_NAME} this
- * method returns the value as login name.
- *
- * <h3>{@link #getPrincipals(String)}</h3>
- * Returns all principals associated with a given user id. This method should
- * be called after a successful authentication in order to be able to populate
- * the subject during {@link #commit()}.
- *
- * <h3>{@link #getPrincipalProvider()}</h3>
- * // TODO
- * <h3>{@link #getUserProvider()}</h3>
- * // TODO
- * <h3>{@link #getSecurityProvider()}</h3>
- * // TODO
- * <h3>{@link #getRoot()}</h3>
- * // TODO
+ * </ol></li>
*
+ * <li>{@link #getSharedCredentials()}: This method returns credentials
+ * passed to the login module with the share state. The key to share credentials
+ * with a another module extending from this base class is
+ * {@link #SHARED_KEY_CREDENTIALS}. Note, that this method does not verify
+ * if the credentials provided by the shared state are
+ * {@link #getSupportedCredentials() supported}.</li>
+ *
+ * <li>{@link #getSharedLoginName()}: If the shared state contains an entry
+ * for {@link #SHARED_KEY_LOGIN_NAME} this method returns the value as login name.</li>
+ *
+ * <li>{@link #getSecurityProvider()}: Returns the configured security
+ * provider or {@code null}.</li>
+ *
+ * <li>{@link #getRoot()}: Provides access to the latest state of the
+ * repository in order to retrieve user or principal information required to
+ * authenticate the subject as well as to write back information during
+ * {@link #commit()}.</li>
+ *
+ * <li>{@link #getUserProvider()}: Returns an instance of the configured
+ * {@link UserProvider} or {@code null}.</li>
+ *
+ * <li>{@link #getPrincipalProvider()}: Returns an instance of the configured
+ * principal provider or {@code null}.</li>
+ *
+ * <li>{@link #getPrincipals(String)}: Utility that returns all principals
+ * associated with a given user id. This method might be be called after
+ * successful authentication in order to be able to populate the subject
+ * during {@link #commit()}. The implementation is a shortcut for calling
+ * {@link PrincipalProvider#getPrincipals(String) getPrincipals(String userId}
+ * on the provider exposed by {@link #getPrincipalProvider()}</li>
+ * </ul>
*/
public abstract class AbstractLoginModule implements LoginModule {
@@ -166,7 +176,6 @@ public abstract class AbstractLoginModul
}
success = true;
}
- // TODO: check if state should be cleared
return success;
}
@@ -185,10 +194,23 @@ public abstract class AbstractLoginModul
root = null;
}
+ /**
+ * @return A set of supported credential classes.
+ */
@Nonnull
protected abstract Set<Class> getSupportedCredentials();
-
+ /**
+ * Tries to retrieve valid (supported) Credentials:
+ * <ol>
+ * <li>using a {@link CredentialsCallback},</li>
+ * <li>looking for a {@link #SHARED_KEY_CREDENTIALS} entry in the
+ * shared state (see also {@link #getSharedCredentials()} and finally by</li>
+ * <li>searching for valid credentials in the subject.</li>
+ * </ol>
+ *
+ * @return Valid (supported) credentials or {@code null}.
+ */
@CheckForNull
protected Credentials getCredentials() {
Set<Class> supported = getSupportedCredentials();
@@ -230,6 +252,10 @@ public abstract class AbstractLoginModul
return null;
}
+ /**
+ * @return The credentials passed to this login module with the shared state.
+ * @see #SHARED_KEY_CREDENTIALS
+ */
@CheckForNull
protected Credentials getSharedCredentials() {
Credentials shared = null;
@@ -245,90 +271,106 @@ public abstract class AbstractLoginModul
return shared;
}
+ /**
+ * @return The login name passed to this login module with the shared state.
+ * @see #SHARED_KEY_LOGIN_NAME
+ */
@CheckForNull
protected String getSharedLoginName() {
if (sharedState.containsKey(SHARED_KEY_LOGIN_NAME)) {
- return (String) sharedState.get(SHARED_KEY_LOGIN_NAME);
+ return sharedState.get(SHARED_KEY_LOGIN_NAME).toString();
} else {
return null;
}
}
+ @CheckForNull
+ protected SecurityProvider getSecurityProvider() {
+ if (securityProvider == null && callbackHandler != null) {
+ SecurityProviderCallback scb = new SecurityProviderCallback();
+ try {
+ callbackHandler.handle(new Callback[] {scb});
+ securityProvider = scb.getSecurityProvider();
+ } catch (UnsupportedCallbackException e) {
+ log.debug(e.getMessage());
+ } catch (IOException e) {
+ log.debug(e.getMessage());
+ }
+ }
+ return securityProvider;
+ }
- @Nonnull
- protected Set<? extends Principal> getPrincipals(String userID) {
- PrincipalProvider principalProvider = getPrincipalProvider();
- if (principalProvider == null) {
- log.debug("Cannot retrieve principals. No principal provider configured.");
- return Collections.emptySet();
- } else {
- return principalProvider.getPrincipals(userID);
+ @CheckForNull
+ protected Root getRoot() {
+ if (root == null && callbackHandler != null) {
+ RepositoryCallback rcb = new RepositoryCallback();
+ try {
+ callbackHandler.handle(new Callback[] {rcb});
+ root = rcb.getRoot();
+ } catch (UnsupportedCallbackException e) {
+ log.debug(e.getMessage());
+ } catch (IOException e) {
+ log.debug(e.getMessage());
+ }
}
+ return root;
}
@CheckForNull
- protected PrincipalProvider getPrincipalProvider() {
- PrincipalProvider principalProvider = null;
+ protected UserProvider getUserProvider() {
+ UserProvider userProvider = null;
SecurityProvider sp = getSecurityProvider();
Root root = getRoot();
if (root != null && sp != null) {
- principalProvider = sp.getPrincipalConfiguration().getPrincipalProvider(root, NamePathMapper.DEFAULT);
+ userProvider = sp.getUserContext().getUserProvider(root);
}
- if (principalProvider == null && callbackHandler != null) {
+ if (userProvider == null && callbackHandler != null) {
try {
- PrincipalProviderCallback principalCallBack = new PrincipalProviderCallback();
- callbackHandler.handle(new Callback[] {principalCallBack});
- principalProvider = principalCallBack.getPrincipalProvider();
+ UserProviderCallback userCallBack = new UserProviderCallback();
+ callbackHandler.handle(new Callback[] {userCallBack});
+ userProvider = userCallBack.getUserProvider();
} catch (IOException e) {
log.debug(e.getMessage());
} catch (UnsupportedCallbackException e) {
log.debug(e.getMessage());
}
}
- return principalProvider;
+
+ return userProvider;
}
@CheckForNull
- protected UserProvider getUserProvider() {
+ protected PrincipalProvider getPrincipalProvider() {
+ PrincipalProvider principalProvider = null;
SecurityProvider sp = getSecurityProvider();
Root root = getRoot();
if (root != null && sp != null) {
- return sp.getUserContext().getUserProvider(root);
- } else {
- return null;
+ principalProvider = sp.getPrincipalConfiguration().getPrincipalProvider(root, NamePathMapper.DEFAULT);
}
- }
- @CheckForNull
- protected SecurityProvider getSecurityProvider() {
- if (securityProvider == null && callbackHandler != null) {
- SecurityProviderCallback scb = new SecurityProviderCallback();
+ if (principalProvider == null && callbackHandler != null) {
try {
- callbackHandler.handle(new Callback[] {scb});
- securityProvider = scb.getSecurityProvider();
- } catch (UnsupportedCallbackException e) {
- log.debug(e.getMessage());
+ PrincipalProviderCallback principalCallBack = new PrincipalProviderCallback();
+ callbackHandler.handle(new Callback[] {principalCallBack});
+ principalProvider = principalCallBack.getPrincipalProvider();
} catch (IOException e) {
log.debug(e.getMessage());
+ } catch (UnsupportedCallbackException e) {
+ log.debug(e.getMessage());
}
}
- return securityProvider;
+ return principalProvider;
}
- @CheckForNull
- protected Root getRoot() {
- if (root == null && callbackHandler != null) {
- RepositoryCallback rcb = new RepositoryCallback();
- try {
- callbackHandler.handle(new Callback[] {rcb});
- root = rcb.getRoot();
- } catch (UnsupportedCallbackException e) {
- log.debug(e.getMessage());
- } catch (IOException e) {
- log.debug(e.getMessage());
- }
+ @Nonnull
+ protected Set<? extends Principal> getPrincipals(String userID) {
+ PrincipalProvider principalProvider = getPrincipalProvider();
+ if (principalProvider == null) {
+ log.debug("Cannot retrieve principals. No principal provider configured.");
+ return Collections.emptySet();
+ } else {
+ return principalProvider.getPrincipals(userID);
}
- return root;
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java?rev=1398676&r1=1398675&r2=1398676&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java Tue Oct 16 07:04:23 2012
@@ -24,7 +24,6 @@ import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import org.apache.jackrabbit.oak.spi.security.authentication.callback.CredentialsCallback;
@@ -73,7 +72,7 @@ import org.slf4j.LoggerFactory;
* In this case calling {@link javax.jcr.Repository#login()} would be equivalent
* to {@link javax.jcr.Repository#login(javax.jcr.Credentials) repository.login(new GuestCredentials()}.
*/
-public class GuestLoginModule implements LoginModule {
+public final class GuestLoginModule implements LoginModule {
private static final Logger log = LoggerFactory.getLogger(GuestLoginModule.class);
@@ -92,7 +91,7 @@ public class GuestLoginModule implements
}
@Override
- public boolean login() throws LoginException {
+ public boolean login() {
if (callbackHandler != null) {
CredentialsCallback ccb = new CredentialsCallback();
try {
@@ -115,7 +114,7 @@ public class GuestLoginModule implements
}
@Override
- public boolean commit() throws LoginException {
+ public boolean commit() {
if (guestCredentials != null && !subject.isReadOnly()) {
subject.getPublicCredentials().add(guestCredentials);
subject.getPrincipals().add(EveryonePrincipal.getInstance());
@@ -124,13 +123,13 @@ public class GuestLoginModule implements
}
@Override
- public boolean abort() throws LoginException {
- // nothing to do
+ public boolean abort() {
+ guestCredentials = null;
return true;
}
@Override
- public boolean logout() throws LoginException {
+ public boolean logout() {
// nothing to do.
return true;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/RepositoryCallback.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/RepositoryCallback.java?rev=1398676&r1=1398675&r2=1398676&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/RepositoryCallback.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/RepositoryCallback.java Tue Oct 16 07:04:23 2012
@@ -30,7 +30,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * RepositoryCallback... TODO
+ * Callback implementation used to access the repository. It allows to set and
+ * get the {@code NodeStore} and the name of the workspace for which the login
+ * applies. In addition it provides access to a {@link Root} object based on
+ * the given node store and workspace name.
*/
public class RepositoryCallback implements Callback {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/SecurityProviderCallback.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/SecurityProviderCallback.java?rev=1398676&r1=1398675&r2=1398676&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/SecurityProviderCallback.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/callback/SecurityProviderCallback.java Tue Oct 16 07:04:23 2012
@@ -22,7 +22,7 @@ import javax.security.auth.callback.Call
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
/**
- * SecurityProviderCallback... TODO
+ * Callback implementation to set and get the {@link SecurityProvider}.
*/
public class SecurityProviderCallback implements Callback {
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModuleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModuleTest.java?rev=1398676&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModuleTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModuleTest.java Tue Oct 16 07:04:23 2012
@@ -0,0 +1,162 @@
+/*
+ * 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.jackrabbit.oak.spi.security.authentication;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.jcr.Credentials;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+
+import org.apache.jackrabbit.oak.spi.security.authentication.callback.CredentialsCallback;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+/**
+ * AbstractLoginModuleTest...
+ */
+public class AbstractLoginModuleTest {
+
+ private AbstractLoginModule initLoginModule(Class supportedCredentials, Map sharedState) {
+ AbstractLoginModule lm = new TestLoginModule(supportedCredentials);
+ lm.initialize(new Subject(), null, sharedState, null);
+ return lm;
+ }
+
+
+ private AbstractLoginModule initLoginModule(Class supportedCredentials, CallbackHandler cbh) {
+ AbstractLoginModule lm = new TestLoginModule(supportedCredentials);
+ lm.initialize(new Subject(), cbh, Collections.<String, Object>emptyMap(), null);
+ return lm;
+ }
+
+ @Test
+ public void testGetSharedLoginName() {
+ Map<String, String> sharedState = new HashMap<String, String>();
+
+ sharedState.put(AbstractLoginModule.SHARED_KEY_LOGIN_NAME, "test");
+ AbstractLoginModule lm = initLoginModule(TestCredentials.class, sharedState);
+ assertEquals("test", lm.getSharedLoginName());
+
+ sharedState.clear();
+ lm = initLoginModule(TestCredentials.class, sharedState);
+ assertNull(lm.getSharedLoginName());
+ }
+
+ @Test
+ public void testGetSharedCredentials() {
+ Map<String, Object> sharedState = new HashMap<String, Object>();
+
+ sharedState.put(AbstractLoginModule.SHARED_KEY_CREDENTIALS, new TestCredentials());
+ AbstractLoginModule lm = initLoginModule(TestCredentials.class, sharedState);
+ assertTrue(lm.getSharedCredentials() instanceof TestCredentials);
+
+ sharedState.put(AbstractLoginModule.SHARED_KEY_CREDENTIALS, new SimpleCredentials("test", "test".toCharArray()));
+ lm = initLoginModule(TestCredentials.class, sharedState);
+ assertTrue(lm.getSharedCredentials() instanceof SimpleCredentials);
+
+ lm = initLoginModule(SimpleCredentials.class, sharedState);
+ assertTrue(lm.getSharedCredentials() instanceof SimpleCredentials);
+
+ sharedState.put(AbstractLoginModule.SHARED_KEY_CREDENTIALS, "no credentials object");
+ lm = initLoginModule(TestCredentials.class, sharedState);
+ assertNull(lm.getSharedCredentials());
+
+ sharedState.clear();
+ lm = initLoginModule(TestCredentials.class, sharedState);
+ assertNull(lm.getSharedCredentials());
+ }
+
+ @Test
+ public void testGetCredentialsFromSharedState() {
+ Map<String, Credentials> sharedState = new HashMap<String, Credentials>();
+
+ sharedState.put(AbstractLoginModule.SHARED_KEY_CREDENTIALS, new TestCredentials());
+ AbstractLoginModule lm = initLoginModule(TestCredentials.class, sharedState);
+ assertTrue(lm.getCredentials() instanceof TestCredentials);
+
+ SimpleCredentials sc = new SimpleCredentials("test", "test".toCharArray());
+ sharedState.put(AbstractLoginModule.SHARED_KEY_CREDENTIALS, sc);
+ lm = initLoginModule(TestCredentials.class, sharedState);
+ assertNull(lm.getCredentials());
+
+ sharedState.put(AbstractLoginModule.SHARED_KEY_CREDENTIALS, sc);
+ lm = initLoginModule(SimpleCredentials.class, sharedState);
+ assertTrue(lm.getCredentials() instanceof SimpleCredentials);
+
+ sharedState.clear();
+ lm = initLoginModule(TestCredentials.class, sharedState);
+ assertNull(lm.getCredentials());
+ }
+
+ public void testGetCredentialsFromCallbackHandler() {
+ CallbackHandler cbh = new CallbackHandler() {
+ @Override
+ public void handle(Callback[] callbacks) {
+ for (Callback cb : callbacks) {
+ if (cb instanceof CredentialsCallback) {
+ ((CredentialsCallback) cb).setCredentials(new TestCredentials());
+ }
+ }
+ }
+ };
+
+ AbstractLoginModule lm = initLoginModule(TestCredentials.class, cbh);
+ assertTrue(lm.getCredentials() instanceof TestCredentials);
+
+ lm = initLoginModule(SimpleCredentials.class, cbh);
+ assertNull(lm.getCredentials());
+ }
+
+ //--------------------------------------------------------------------------
+
+ private final class TestCredentials implements Credentials {}
+
+ private final class TestLoginModule extends AbstractLoginModule {
+
+ private Class supportedCredentialsClass;
+
+ private TestLoginModule(Class supportedCredentialsClass) {
+ this.supportedCredentialsClass = supportedCredentialsClass;
+ }
+
+ @Nonnull
+ @Override
+ protected Set<Class> getSupportedCredentials() {
+ return Collections.singleton(supportedCredentialsClass);
+ }
+
+ @Override
+ public boolean login() throws LoginException {
+ return true;
+ }
+
+ @Override
+ public boolean commit() throws LoginException {
+ return true;
+ }
+ }
+}
\ No newline at end of file