You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2011/02/16 14:35:59 UTC

svn commit: r1071241 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/security/authentication/ test/java/org/apache/jackrabbit/core/integration/ test/java/org/apache/jackrabbit/core/security/authentication/ test/java/org...

Author: angela
Date: Wed Feb 16 13:35:58 2011
New Revision: 1071241

URL: http://svn.apache.org/viewvc?rev=1071241&view=rev
Log:
JCR-2851 - Authentication Mechanism Based on Login Token
JCR-2894 - AbstractLoginModule#logout() : credentials will not be clared as Subject.getPublicCredentials(Class) isn't backed by the subject internal set

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/SessionImplTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModuleTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/token/TokenBasedLoginTest.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java?rev=1071241&r1=1071240&r2=1071241&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java Wed Feb 16 13:35:58 2011
@@ -415,14 +415,14 @@ public abstract class AbstractLoginModul
      * @see javax.security.auth.spi.LoginModule#logout()
      */
     public boolean logout() throws LoginException {
-        Set<Principal> thisPrincipals = subject.getPrincipals();
-        Set<SimpleCredentials> thisCredentials = subject.getPublicCredentials(SimpleCredentials.class);
-        if (thisPrincipals == null || thisCredentials == null
-                || thisPrincipals.isEmpty() || thisCredentials.isEmpty()) {
+        if (subject.getPrincipals().isEmpty() || subject.getPublicCredentials(Credentials.class).isEmpty()) {
             return false;
         } else {
-            thisPrincipals.clear();
-            thisCredentials.clear();
+            // clear subject if not readonly
+            if (!subject.isReadOnly()) {
+                subject.getPrincipals().clear();
+                subject.getPublicCredentials().clear();
+            }
             return true;
         }
     }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java?rev=1071241&r1=1071240&r2=1071241&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java Wed Feb 16 13:35:58 2011
@@ -79,10 +79,9 @@ public class DefaultLoginModule extends 
     private UserManager userManager;
 
     /**
-     * The login token extracted from TokenCredentials or null in case of
-     * another credentials.
+     * The TokenCredentials or null in case of another credentials.
      */
-    private String loginToken;
+    private TokenCredentials tokenCredentials;
 
     //--------------------------------------------------------< LoginModule >---
     /**
@@ -91,27 +90,31 @@ public class DefaultLoginModule extends 
     @Override
     public boolean commit() throws LoginException {
         boolean success = super.commit();
-        if (success && !disableTokenAuth && TokenBasedAuthentication.doCreateToken(credentials)) {
-            Session s = null;
-            try {
-                /*
-                use a different session instance to create the token
-                node in order to prevent concurrent modifications with
-                the shared system session.
-                */
-                s = session.createSession(session.getWorkspace().getName());
-                Credentials tc = TokenBasedAuthentication.createToken(user, credentials, tokenExpiration, s);
-                if (tc != null) {
-                    subject.getPublicCredentials().add(tc);
-                }
-            } catch (RepositoryException e) {
-                LoginException le = new LoginException("Failed to commit: " + e.getMessage());
-                le.initCause(e);
-                throw le;
-            } finally {
-                if (s != null) {
-                    s.logout();
+        if (success && !disableTokenAuth) {
+            if (TokenBasedAuthentication.doCreateToken(credentials)) {
+                Session s = null;
+                try {
+                    /*
+                    use a different session instance to create the token
+                    node in order to prevent concurrent modifications with
+                    the shared system session.
+                    */
+                    s = session.createSession(session.getWorkspace().getName());
+                    Credentials tc = TokenBasedAuthentication.createToken(user, credentials, tokenExpiration, s);
+                    if (tc != null) {
+                        subject.getPublicCredentials().add(tc);
+                    }
+                } catch (RepositoryException e) {
+                    LoginException le = new LoginException("Failed to commit: " + e.getMessage());
+                    le.initCause(e);
+                    throw le;
+                } finally {
+                    if (s != null) {
+                        s.logout();
+                    }
                 }
+            } else if (tokenCredentials != null) {
+                subject.getPublicCredentials().add(tokenCredentials);
             }
         }
         return success;
@@ -200,9 +203,9 @@ public class DefaultLoginModule extends 
         // handle TokenCredentials
         if (!disableTokenAuth && TokenBasedAuthentication.isTokenBasedLogin(credentials)) {
             // special token based login
-            loginToken = ((TokenCredentials) credentials).getToken();
+            tokenCredentials = ((TokenCredentials) credentials);
             try {
-                Node n = session.getNodeByIdentifier(loginToken);
+                Node n = session.getNodeByIdentifier(tokenCredentials.getToken());
                 final NodeImpl userNode = (NodeImpl) n.getParent().getParent();
                 final String principalName = userNode.getProperty(UserImpl.P_PRINCIPAL_NAME).getString();
                 if (userNode.isNodeType(UserImpl.NT_REP_USER)) {
@@ -236,8 +239,8 @@ public class DefaultLoginModule extends 
      */
     @Override
     protected Authentication getAuthentication(Principal principal, Credentials creds) throws RepositoryException {
-        if (!disableTokenAuth && loginToken != null) {
-            Authentication authentication = new TokenBasedAuthentication(loginToken, tokenExpiration, session);
+        if (!disableTokenAuth && tokenCredentials != null) {
+            Authentication authentication = new TokenBasedAuthentication(tokenCredentials.getToken(), tokenExpiration, session);
             if (authentication.canHandle(creds)) {
                 return authentication;
             }

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/SessionImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/SessionImplTest.java?rev=1071241&r1=1071240&r2=1071241&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/SessionImplTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/SessionImplTest.java Wed Feb 16 13:35:58 2011
@@ -105,6 +105,7 @@ public class SessionImplTest extends Abs
         } finally {
             s1.logout();
             assertFalse(subject.getPrincipals().isEmpty());
+            assertFalse(subject.getPublicCredentials().isEmpty());
         }
 
 
@@ -117,6 +118,7 @@ public class SessionImplTest extends Abs
         } finally {
             s2.logout();
             assertFalse(subject.getPrincipals().isEmpty());
+            assertFalse(subject.getPublicCredentials().isEmpty());
         }
 
         Session s3 = sImpl.createSession(null);
@@ -128,6 +130,7 @@ public class SessionImplTest extends Abs
         } finally {
             s3.logout();
             assertFalse(subject.getPrincipals().isEmpty());
+            assertFalse(subject.getPublicCredentials().isEmpty());
         }
     }
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModuleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModuleTest.java?rev=1071241&r1=1071240&r2=1071241&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModuleTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModuleTest.java Wed Feb 16 13:35:58 2011
@@ -69,6 +69,9 @@ public class DefaultLoginModuleTest exte
             "   <param name=\"disableTokenAuth\" value=\"true\"/>\n" +
             "</LoginModule>" +
             "</Security>";
+    
+    private SimpleCredentials simpleCredentials = new SimpleCredentials("admin", "admin".toCharArray());
+    private Session securitySession;
 
     @Override
     protected void setUp() throws Exception {
@@ -90,16 +93,89 @@ public class DefaultLoginModuleTest exte
         super.cleanUp();
     }
 
-    private SimpleCredentials simpleCredentials = new SimpleCredentials("admin", "admin".toCharArray());
-    private Session securitySession;
-
     public void testSimpleCredentialsLogin() throws Exception {
         AuthContext ac = getAuthContext(simpleCredentials, DEFAULT_CONFIG);
         ac.login();
         ac.logout();
     }
 
-    public void testTokenCredentials() throws Exception {
+    public void testSimpleCredentialsLoginLogout() throws Exception {
+        AuthContext ac = getAuthContext(simpleCredentials, DEFAULT_CONFIG);
+        ac.login();
+
+        Subject subject = ac.getSubject();
+        assertFalse(subject.getPrincipals().isEmpty());
+        assertFalse(subject.getPublicCredentials().isEmpty());
+        assertFalse(subject.getPublicCredentials(SimpleCredentials.class).isEmpty());
+
+        ac.logout();
+        assertTrue(subject.getPrincipals().isEmpty());
+        assertTrue(subject.getPublicCredentials().isEmpty());
+        assertTrue(subject.getPublicCredentials(SimpleCredentials.class).isEmpty());
+    }
+
+    public void testTokenCredentialsLoginLogout() throws Exception {
+        simpleCredentials.setAttribute(TokenBasedAuthentication.TOKEN_ATTRIBUTE, "");
+        try {
+            // login with simple credentials forcing token creation.
+            AuthContext ac = getAuthContext(simpleCredentials, DEFAULT_CONFIG);
+            ac.login();
+
+            Subject subject = ac.getSubject();
+
+            assertFalse(subject.getPrincipals().isEmpty());
+            assertFalse(subject.getPublicCredentials().isEmpty());
+            assertFalse(subject.getPublicCredentials(SimpleCredentials.class).isEmpty());
+            assertFalse(subject.getPublicCredentials(TokenCredentials.class).isEmpty());
+            assertEquals(2, subject.getPublicCredentials(Credentials.class).size());
+
+            TokenCredentials tokenCredentials = subject.getPublicCredentials(TokenCredentials.class).iterator().next();
+
+            ac.logout();
+
+            // second login with token credentials
+            ac = getAuthContext(tokenCredentials, DEFAULT_CONFIG);
+            ac.login();
+
+            subject = ac.getSubject();
+
+            assertFalse(subject.getPrincipals().isEmpty());
+            assertFalse(subject.getPublicCredentials().isEmpty());
+            assertFalse(subject.getPublicCredentials(SimpleCredentials.class).isEmpty());
+            assertFalse(subject.getPublicCredentials(TokenCredentials.class).isEmpty());
+            assertEquals(2, subject.getPublicCredentials(Credentials.class).size());
+
+            ac.logout();
+            assertTrue(subject.getPrincipals().isEmpty());            
+            assertTrue(subject.getPublicCredentials().isEmpty());
+            assertTrue(subject.getPublicCredentials(SimpleCredentials.class).isEmpty());
+            assertTrue(subject.getPublicCredentials(TokenCredentials.class).isEmpty());
+        } finally {
+            simpleCredentials.removeAttribute(TokenBasedAuthentication.TOKEN_ATTRIBUTE);
+        }
+    }
+
+    public void testDisabledTokenCredentials() throws Exception {
+        simpleCredentials.setAttribute(TokenBasedAuthentication.TOKEN_ATTRIBUTE, "");
+        try {
+            AuthContext ac = getAuthContext(simpleCredentials, DISABLE_TOKEN_CONFIG);
+            ac.login();
+
+            Subject subject = ac.getSubject();
+
+            assertFalse(subject.getPrincipals().isEmpty());
+            assertFalse(subject.getPublicCredentials().isEmpty());
+            assertFalse(subject.getPublicCredentials(SimpleCredentials.class).isEmpty());
+            assertTrue(subject.getPublicCredentials(TokenCredentials.class).isEmpty());
+            assertEquals(1, subject.getPublicCredentials(Credentials.class).size());
+
+            ac.logout();
+        } finally {
+            simpleCredentials.removeAttribute(TokenBasedAuthentication.TOKEN_ATTRIBUTE);
+        }
+    }
+
+    public void testDisabledTokenCredentials2() throws Exception {
         simpleCredentials.setAttribute(TokenBasedAuthentication.TOKEN_ATTRIBUTE, "");
         try {
             AuthContext ac = getAuthContext(simpleCredentials, DEFAULT_CONFIG);

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/token/TokenBasedLoginTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/token/TokenBasedLoginTest.java?rev=1071241&r1=1071240&r2=1071241&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/token/TokenBasedLoginTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/token/TokenBasedLoginTest.java Wed Feb 16 13:35:58 2011
@@ -67,9 +67,6 @@ public class TokenBasedLoginTest extends
             Principal p = testuser.getPrincipal();
             if (p instanceof ItemBasedPrincipal) {
                 testuserPath = ((ItemBasedPrincipal) p).getPath();
-                if (!superuser.nodeExists(testuserPath)) {
-                    throw new NotExecutableException();
-                }
             } else {
                 throw new NotExecutableException();
             }
@@ -117,29 +114,35 @@ public class TokenBasedLoginTest extends
             Set<TokenCredentials> tokenCreds = ((SessionImpl) s).getSubject().getPublicCredentials(TokenCredentials.class);
             assertFalse(tokenCreds.isEmpty());
             assertEquals(1, tokenCreds.size());
-            TokenCredentials tc = tokenCreds.iterator().next();
-            assertEquals(tc.getToken(), s.getAttribute(TOKEN_ATTRIBUTE));
+
+            TokenCredentials tc = tokenCreds.iterator().next();          
+            token = tc.getToken();
+
+            assertEquals(token, s.getAttribute(TOKEN_ATTRIBUTE));
             for (String attrName : tc.getAttributeNames()) {
                 assertEquals(tc.getAttribute(attrName), s.getAttribute(attrName));
             }
-            assertEquals(tc.getToken(), s.getAttribute(TOKEN_ATTRIBUTE));
 
-            Node userNode = superuser.getNode(testuserPath);
+            // only test node characteristics if user-node resided within the same
+            // workspace as 'superuser' has been created for.
+            if (superuser.nodeExists(testuserPath)) {
+                Node userNode = superuser.getNode(testuserPath);
 
-            assertTrue(userNode.hasNode(TOKENS_NAME));
+                assertTrue(userNode.hasNode(TOKENS_NAME));
 
-            Node tNode = userNode.getNode(TOKENS_NAME);
-            assertTrue(tNode.hasNodes());
+                Node tNode = userNode.getNode(TOKENS_NAME);
+                assertTrue(tNode.hasNodes());
 
-            Node ttNode = tNode.getNodes().nextNode();
-            assertTrue(ttNode.hasProperty("attr"));
-            assertEquals("attr", ttNode.getProperty("attr").getString());
+                Node ttNode = tNode.getNodes().nextNode();
+                assertTrue(ttNode.hasProperty("attr"));
+                assertEquals("attr", ttNode.getProperty("attr").getString());
 
-            assertTrue(ttNode.hasProperty(TOKEN_ATTRIBUTE + ".any"));
-            assertEquals("any", ttNode.getProperty(TOKEN_ATTRIBUTE + ".any").getString());
+                assertTrue(ttNode.hasProperty(TOKEN_ATTRIBUTE + ".any"));
+                assertEquals("any", ttNode.getProperty(TOKEN_ATTRIBUTE + ".any").getString());
 
-            token = ttNode.getIdentifier();
-            assertEquals(token, tc.getToken());
+                String id = ttNode.getIdentifier();
+                assertEquals(token, id);
+            }
 
         } finally {
             s.logout();
@@ -152,6 +155,19 @@ public class TokenBasedLoginTest extends
         s = repo.login(tokenOnly);
         try {
             assertEquals(creds.getUserID(), s.getUserID());
+
+            Set<TokenCredentials> tokenCreds = ((SessionImpl) s).getSubject().getPublicCredentials(TokenCredentials.class);
+            assertFalse(tokenCreds.isEmpty());
+            assertEquals(1, tokenCreds.size());
+
+            TokenCredentials tc = tokenCreds.iterator().next();
+            token = tc.getToken();
+
+            assertEquals(token, s.getAttribute(TOKEN_ATTRIBUTE));
+            for (String attrName : tc.getAttributeNames()) {
+                assertEquals(tc.getAttribute(attrName), s.getAttribute(attrName));
+            }
+
         } finally {
             s.logout();
         }