Author: angela
Date: Wed Oct 31 15:09:27 2012
New Revision: 1404185

URL: http://svn.apache.org/viewvc?rev=1404185&view=rev
Log:
 OAK-91 - Implement Authentication Support (WIP)

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthentication.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModule.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java?rev=1404185&r1=1404184&r2=1404185&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java
 Wed Oct 31 15:09:27 2012
@@ -72,22 +72,24 @@ import org.slf4j.LoggerFactory;
  *     <li>{@link ImpersonationCredentials}</li>
  * </ul>
  *
- * The {@link Credentials} obtained during the {@link #login()} are added to
- * the shared state and - upon successful {@link #commit()} to the {@link 
Subject}.
+ * The {@link Credentials} obtained during the {@code #login()} are added to
+ * the shared state and - upon successful {@code #commit()} to the {@code 
Subject}.
  *
  * <h3>Principals</h3>
- *
- * TODO
- * - principal lookup -> principal provider
- * - principal resolution based on credentials
+ * Upon successful login the principals associated with the user are calculated
+ * (see also {@link AbstractLoginModule#getPrincipals(String)}. These 
principals
+ * are finally added to the subject during {@code #commit()}.
  *
  * <h3>Impersonation</h3>
- *
- * TODO
- *
- *
- *
- *
+ * Impersonation such as defined by {@link 
javax.jcr.Session#impersonate(javax.jcr.Credentials)}
+ * is covered by this login module by the means of {@link 
ImpersonationCredentials}.
+ * Impersonation will succeed if the {@link 
ImpersonationCredentials#getBaseCredentials() base credentials}
+ * refer to a valid user that has not been disabled. If the authenticating
+ * subject is not allowed to impersonate the specified user, the login attempt
+ * will fail with {@code LoginException}.<p/>
+ * Please note, that a user will always be allowed to impersonate him/herself
+ * irrespective of the impersonation definitions exposed by
+ * {@link org.apache.jackrabbit.api.security.user.User#getImpersonation()}
  */
 public final class LoginModuleImpl extends AbstractLoginModule {
 
@@ -116,7 +118,7 @@ public final class LoginModuleImpl exten
             return false;
         }
 
-        Authentication authentication = new UserAuthentication(userId, 
getUserManager(), getPrincipalProvider());
+        Authentication authentication = new UserAuthentication(userId, 
getUserManager());
         boolean success = authentication.authenticate(credentials);
         if (success) {
             principals = getPrincipals(userId);

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthentication.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthentication.java?rev=1404185&r1=1404184&r2=1404185&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthentication.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthentication.java
 Wed Oct 31 15:09:27 2012
@@ -31,7 +31,6 @@ import org.apache.jackrabbit.oak.api.Aut
 import org.apache.jackrabbit.oak.security.user.CredentialsImpl;
 import org.apache.jackrabbit.oak.spi.security.authentication.Authentication;
 import 
org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials;
-import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
 import org.apache.jackrabbit.oak.spi.security.user.util.PasswordUtility;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,12 +62,10 @@ class UserAuthentication implements Auth
 
     private final String userId;
     private final UserManager userManager;
-    private final PrincipalProvider principalProvider;
 
-    UserAuthentication(String userId, UserManager userManager, 
PrincipalProvider principalProvider) {
+    UserAuthentication(String userId, UserManager userManager) {
         this.userId = userId;
         this.userManager = userManager;
-        this.principalProvider = principalProvider;
     }
 
     @Override
@@ -120,9 +117,15 @@ class UserAuthentication implements Auth
     }
 
     private boolean impersonate(AuthInfo info, User user) {
-        Subject subject = new Subject(true, info.getPrincipals(), 
Collections.emptySet(), Collections.emptySet());
         try {
-            return user.getImpersonation().allows(subject);
+            if (info.getUserID().equals(user.getID())) {
+                log.debug("User " + info.getUserID() + " wants to impersonate 
himself -> success.");
+                return true;
+            } else {
+                log.debug("User " + info.getUserID() + " wants to impersonate 
" + user.getID());
+                Subject subject = new Subject(true, info.getPrincipals(), 
Collections.emptySet(), Collections.emptySet());
+                return user.getImpersonation().allows(subject);
+            }
         } catch (RepositoryException e) {
             log.debug("Error while validating impersonation", e.getMessage());
         }

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=1404185&r1=1404184&r2=1404185&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
 Wed Oct 31 15:09:27 2012
@@ -363,14 +363,22 @@ public abstract class AbstractLoginModul
         return principalProvider;
     }
 
+    /**
+     * Retrieves all principals associated with the specified {@code userId} 
for
+     * the configured principal provider.
+     *
+     * @param userId The id of the user.
+     * @return The set of principals associated with the given {@code userId}.
+     * @see #getPrincipalProvider()
+     */
     @Nonnull
-    protected Set<? extends Principal> getPrincipals(String userID) {
+    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 principalProvider.getPrincipals(userId);
         }
     }
 }

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java?rev=1404185&r1=1404184&r2=1404185&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java
 Wed Oct 31 15:09:27 2012
@@ -32,6 +32,7 @@ import org.apache.jackrabbit.oak.api.Roo
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.security.AbstractSecurityTest;
 import org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl;
+import 
org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials;
 import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
 import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
 import org.apache.jackrabbit.oak.spi.security.user.util.UserUtility;
@@ -149,4 +150,81 @@ public class DefaultLoginModuleTest exte
         }
     }
 
+    @Test
+    public void testSelfImpersonation() throws Exception {
+        Root root = admin.getLatestRoot();
+        UserManager userManager = uc.getUserManager(root, 
NamePathMapper.DEFAULT);
+
+        ContentSession cs = null;
+        User user = null;
+        try {
+            user = userManager.createUser("test", "pw");
+            root.commit();
+
+            SimpleCredentials sc = new SimpleCredentials("test", 
"pw".toCharArray());
+            cs = login(sc);
+
+            AuthInfo authInfo = cs.getAuthInfo();
+            assertEquals("test", authInfo.getUserID());
+
+            cs.close();
+
+            sc = new SimpleCredentials("test", new char[0]);
+            ImpersonationCredentials ic = new ImpersonationCredentials(sc, 
authInfo);
+            cs = login(ic);
+
+            authInfo = cs.getAuthInfo();
+            assertEquals("test", authInfo.getUserID());
+        } finally {
+            if (user != null) {
+                user.remove();
+                root.commit();
+            }
+            if (cs != null) {
+                cs.close();
+            }
+        }
+    }
+
+    @Test
+    public void testInvalidImpersonation() throws Exception {
+        Root root = admin.getLatestRoot();
+        UserManager userManager = uc.getUserManager(root, 
NamePathMapper.DEFAULT);
+
+        ContentSession cs = null;
+        User user = null;
+        try {
+            user = userManager.createUser("test", "pw");
+            root.commit();
+
+            SimpleCredentials sc = new SimpleCredentials("test", 
"pw".toCharArray());
+            cs = login(sc);
+
+            AuthInfo authInfo = cs.getAuthInfo();
+            assertEquals("test", authInfo.getUserID());
+
+            cs.close();
+            cs = null;
+
+            String adminId = 
UserUtility.getAdminId(securityProvider.getUserConfiguration().getConfigurationParameters());
+            sc = new SimpleCredentials(adminId, new char[0]);
+            ImpersonationCredentials ic = new ImpersonationCredentials(sc, 
authInfo);
+
+            try {
+                cs = login(ic);
+                fail("User 'test' should not be allowed to impersonate " + 
adminId);
+            } catch (LoginException e) {
+                // success
+            }
+        } finally {
+            if (user != null) {
+                user.remove();
+                root.commit();
+            }
+            if (cs != null) {
+                cs.close();
+            }
+        }
+    }
+
 }


Reply via email to