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 2013/10/02 17:24:57 UTC
svn commit: r1528518 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/security/authentication/token/
main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/
test/java/org/apache/jackrabbit/oak/security/authent...
Author: angela
Date: Wed Oct 2 15:24:56 2013
New Revision: 1528518
URL: http://svn.apache.org/r1528518
Log:
OAK-608 : Pluggable Authentication (WIP)
- refactor token provider to simplify pluggability
- add CompositeTokenProvider that allows to aggregate multiple tokenprovider implementations
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenProvider.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenInfo.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenInfoTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java?rev=1528518&r1=1528517&r2=1528518&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java Wed Oct 2 15:24:56 2013
@@ -87,12 +87,12 @@ class TokenAuthentication implements Aut
if (tokenInfo.isExpired(loginTime)) {
// token is expired
log.debug("Token is expired");
- tokenProvider.removeToken(tokenInfo);
+ tokenInfo.remove();
return false;
}
if (tokenInfo.matches(tokenCredentials)) {
- tokenProvider.resetTokenExpiration(tokenInfo, loginTime);
+ tokenInfo.resetExpiration(loginTime);
return true;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java?rev=1528518&r1=1528517&r2=1528518&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java Wed Oct 2 15:24:56 2013
@@ -279,50 +279,6 @@ public class TokenProviderImpl implement
}
}
- @Override
- public boolean removeToken(TokenInfo tokenInfo) {
- Tree tokenTree = getTokenTree(tokenInfo);
- if (tokenTree != null && tokenTree.exists()) {
- try {
- if (tokenTree.remove()) {
- root.commit();
- return true;
- }
- } catch (CommitFailedException e) {
- log.debug("Error while removing expired token", e.getMessage());
- }
- }
- return false;
- }
-
- @Override
- public boolean resetTokenExpiration(TokenInfo tokenInfo, long loginTime) {
- Tree tokenTree = getTokenTree(tokenInfo);
- if (tokenTree != null && tokenTree.exists()) {
- NodeUtil tokenNode = new NodeUtil(tokenTree);
- long expTime = getExpirationTime(tokenNode, 0);
- if (tokenInfo.isExpired(loginTime)) {
- log.debug("Attempt to reset an expired token.");
- return false;
- }
-
- long expiration = tokenNode.getLong(PARAM_TOKEN_EXPIRATION, tokenExpiration);
- if (expTime - loginTime <= expiration / 2) {
- long expirationTime = createExpirationTime(loginTime, expiration);
- try {
- tokenNode.setDate(TOKEN_ATTRIBUTE_EXPIRY, expirationTime);
- root.commit();
- log.debug("Successfully reset token expiration time.");
- return true;
- } catch (CommitFailedException e) {
- log.warn("Error while resetting token expiration", e.getMessage());
- }
- }
- }
- return false;
- }
-
-
//--------------------------------------------------------------------------
private static long createExpirationTime(long creationTime, long tokenExpiration) {
return creationTime + tokenExpiration;
@@ -429,7 +385,7 @@ public class TokenProviderImpl implement
/**
* TokenInfo
*/
- private static final class TokenInfoImpl implements TokenInfo {
+ private final class TokenInfoImpl implements TokenInfo {
private final String token;
private final String tokenPath;
@@ -485,6 +441,49 @@ public class TokenProviderImpl implement
}
@Override
+ public boolean resetExpiration(long loginTime) {
+ Tree tokenTree = getTokenTree(this);
+ if (tokenTree != null && tokenTree.exists()) {
+ NodeUtil tokenNode = new NodeUtil(tokenTree);
+ long expTime = getExpirationTime(tokenNode, 0);
+ if (isExpired(loginTime)) {
+ log.debug("Attempt to reset an expired token.");
+ return false;
+ }
+
+ long expiration = tokenNode.getLong(PARAM_TOKEN_EXPIRATION, tokenExpiration);
+ if (expTime - loginTime <= expiration / 2) {
+ long expirationTime = createExpirationTime(loginTime, expiration);
+ try {
+ tokenNode.setDate(TOKEN_ATTRIBUTE_EXPIRY, expirationTime);
+ root.commit();
+ log.debug("Successfully reset token expiration time.");
+ return true;
+ } catch (CommitFailedException e) {
+ log.warn("Error while resetting token expiration", e.getMessage());
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean remove() {
+ Tree tokenTree = getTokenTree(this);
+ if (tokenTree != null && tokenTree.exists()) {
+ try {
+ if (tokenTree.remove()) {
+ root.commit();
+ return true;
+ }
+ } catch (CommitFailedException e) {
+ log.debug("Error while removing expired token", e.getMessage());
+ }
+ }
+ return false;
+ }
+
+ @Override
public boolean matches(TokenCredentials tokenCredentials) {
String tk = tokenCredentials.getToken();
int pos = tk.lastIndexOf(DELIM);
@@ -532,7 +531,7 @@ public class TokenProviderImpl implement
* @return {@code true} if the specified {@code attributeName}
* starts with or equals {@link #TOKEN_ATTRIBUTE}.
*/
- private static boolean isMandatoryAttribute(String attributeName) {
+ private boolean isMandatoryAttribute(String attributeName) {
return attributeName != null && attributeName.startsWith(TOKEN_ATTRIBUTE);
}
@@ -546,7 +545,7 @@ public class TokenProviderImpl implement
* @return {@code true} if the specified property name doesn't seem
* to represent repository internal information.
*/
- private static boolean isInfoAttribute(String attributeName) {
+ private boolean isInfoAttribute(String attributeName) {
String prefix = Text.getNamespacePrefix(attributeName);
return !NamespaceConstants.RESERVED_PREFIXES.contains(prefix);
}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenProvider.java?rev=1528518&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenProvider.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenProvider.java Wed Oct 2 15:24:56 2013
@@ -0,0 +1,117 @@
+/*
+ * 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.token;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.jcr.Credentials;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Aggregates a collection of {@link TokenProvider}s into a single
+ * provider.
+ */
+public class CompositeTokenProvider implements TokenProvider {
+
+ private final List<TokenProvider> providers;
+
+ private CompositeTokenProvider(@Nonnull List<? extends TokenProvider> providers) {
+ this.providers = ImmutableList.copyOf(providers);
+ }
+
+ @Nonnull
+ public static TokenProvider newInstance(@Nonnull TokenProvider... providers) {
+ return newInstance(Arrays.<TokenProvider>asList(providers));
+ }
+
+ @Nonnull
+ public static TokenProvider newInstance(@Nonnull List<? extends TokenProvider> providers) {
+ switch (providers.size()) {
+ case 0: return NULL_PROVIDER;
+ case 1: return providers.iterator().next();
+ default: return new CompositeTokenProvider(providers);
+ }
+ }
+
+ @Override
+ public boolean doCreateToken(@Nonnull Credentials credentials) {
+ for (TokenProvider tp : providers) {
+ if (tp.doCreateToken(credentials)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public TokenInfo createToken(@Nonnull Credentials credentials) {
+ for (TokenProvider tp : providers) {
+ TokenInfo info = tp.createToken(credentials);
+ if (info != null) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public TokenInfo createToken(@Nonnull String userId, @Nonnull Map<String, ?> attributes) {
+ for (TokenProvider tp : providers) {
+ TokenInfo info = tp.createToken(userId, attributes);
+ if (info != null) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public TokenInfo getTokenInfo(@Nonnull String token) {
+ for (TokenProvider tp : providers) {
+ TokenInfo info = tp.getTokenInfo(token);
+ if (info != null) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ private static final TokenProvider NULL_PROVIDER = new TokenProvider() {
+ @Override
+ public boolean doCreateToken(@Nonnull Credentials credentials) {
+ return false;
+ }
+
+ @Override
+ public TokenInfo createToken(@Nonnull Credentials credentials) {
+ return null;
+ }
+
+ @Override
+ public TokenInfo createToken(@Nonnull String userId, @Nonnull Map<String, ?> attributes) {
+ return null;
+ }
+
+ @Override
+ public TokenInfo getTokenInfo(@Nonnull String token) {
+ return null;
+ }
+ };
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenInfo.java?rev=1528518&r1=1528517&r2=1528518&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenInfo.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenInfo.java Wed Oct 2 15:24:56 2013
@@ -53,6 +53,27 @@ public interface TokenInfo {
boolean isExpired(long loginTime);
/**
+ * Resets the expiration time of the login token associated with the given
+ * {@code TokenInfo}. Whether and when the expiration time of a given login
+ * token is being reset is an implementation detail. Implementations that
+ * don't allow for resetting the token's expiration time at all will always
+ * return {@code false}.
+ *
+ * @param loginTime The current login time.
+ * @return {@code true} if the expiration time has been reset, false otherwise.
+ */
+ boolean resetExpiration(long loginTime);
+
+ /**
+ * Tries to remove the login token and all related information. This method
+ * returns {@code true} if the removal was successful.
+ *
+ *
+ * @return {@code true} if the removal was successful, {@code false} otherwise.
+ */
+ boolean remove();
+
+ /**
* Returns {@code true} if the specified credentials can be successfully
* validated against the information stored in this instance.
*
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java?rev=1528518&r1=1528517&r2=1528518&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java Wed Oct 2 15:24:56 2013
@@ -83,28 +83,4 @@ public interface TokenProvider {
*/
@CheckForNull
TokenInfo getTokenInfo(@Nonnull String token);
-
- /**
- * Tries to remove the login token and all related information. This method
- * returns {@code true} if the removal was successful.
- *
- * @param tokenInfo The {@code TokenInfo} associated with the login token to
- * be removed.
- * @return {@code true} if the removal was successful, {@code false} otherwise.
- */
- boolean removeToken(@Nonnull TokenInfo tokenInfo);
-
- /**
- * Resets the expiration time of the login token associated with the given
- * {@code TokenInfo}. Whether and when the expiration time of a given login
- * token is being reset is an implementation detail. Implementations that
- * don't allow for resetting the token's expiration time at all will always
- * return {@code false}.
- *
- * @param tokenInfo The {@code TokenInfo} associated with the login token to
- * be reset.
- * @param loginTime The current login time.
- * @return {@code true} if the expiration time has been reset, false otherwise.
- */
- boolean resetTokenExpiration(@Nonnull TokenInfo tokenInfo, long loginTime);
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenInfoTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenInfoTest.java?rev=1528518&r1=1528517&r2=1528518&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenInfoTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenInfoTest.java Wed Oct 2 15:24:56 2013
@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.jackrabbit.api.security.authentication.token.TokenCredentials;
+import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenInfo;
import org.junit.Before;
import org.junit.Test;
@@ -141,4 +142,48 @@ public class TokenInfoTest extends Abstr
assertFalse("reserved attribute "+key,pubAttr.containsKey(key));
}
}
+
+ @Test
+ public void testRemoveToken() throws Exception {
+ TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+ assertTrue(info.remove());
+ }
+
+ @Test
+ public void testRemoveToken2() throws Exception {
+ TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+ assertTrue(info.remove());
+ }
+
+ @Test
+ public void testRemoveTokenRemovesNode() throws Exception {
+ TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+
+ Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath());
+ Tree tokens = userTree.getChild(".tokens");
+ String tokenNodePath = tokens.getChildren().iterator().next().getPath();
+
+ info.remove();
+ assertFalse(root.getTree(tokenNodePath).exists());
+ }
+
+ @Test
+ public void testResetTokenExpirationExpiredToken() throws Exception {
+ TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+
+ long expiredTime = new Date().getTime() + 7200001;
+ assertTrue(info.isExpired(expiredTime));
+ assertFalse(info.resetExpiration(expiredTime));
+ }
+
+ @Test
+ public void testResetTokenExpiration() throws Exception {
+ TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+
+ assertFalse(info.resetExpiration(new Date().getTime()));
+
+ long loginTime = new Date().getTime() + 3600000;
+ assertFalse(info.isExpired(loginTime));
+ assertTrue(info.resetExpiration(loginTime));
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java?rev=1528518&r1=1528517&r2=1528518&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java Wed Oct 2 15:24:56 2013
@@ -23,7 +23,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
-import javax.annotation.Nonnull;
import javax.jcr.Credentials;
import javax.jcr.GuestCredentials;
import javax.jcr.SimpleCredentials;
@@ -193,60 +192,6 @@ public class TokenProviderImplTest exten
}
@Test
- public void testRemoveTokenInvalidInfo() throws Exception {
- assertFalse(tokenProvider.removeToken(new InvalidTokenInfo()));
- }
-
- @Test
- public void testRemoveToken() throws Exception {
- TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
- assertTrue(tokenProvider.removeToken(info));
- }
-
- @Test
- public void testRemoveToken2() throws Exception {
- TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
- assertTrue(tokenProvider.removeToken(tokenProvider.getTokenInfo(info.getToken())));
- }
-
- @Test
- public void testRemoveTokenRemovesNode() throws Exception {
- TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
-
- Tree userTree = root.getTree(getUserManager(root).getAuthorizable(userId).getPath());
- Tree tokens = userTree.getChild(".tokens");
- String tokenNodePath = tokens.getChildren().iterator().next().getPath();
-
- tokenProvider.removeToken(info);
- assertFalse(root.getTree(tokenNodePath).exists());
- }
-
- @Test
- public void testResetTokenExpirationInvalidToken() throws Exception {
- assertFalse(tokenProvider.resetTokenExpiration(new InvalidTokenInfo(), new Date().getTime()));
- }
-
- @Test
- public void testResetTokenExpirationExpiredToken() throws Exception {
- TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
-
- long expiredTime = new Date().getTime() + 7200001;
- assertTrue(info.isExpired(expiredTime));
- assertFalse(tokenProvider.resetTokenExpiration(info, expiredTime));
- }
-
- @Test
- public void testResetTokenExpiration() throws Exception {
- TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
-
- assertFalse(tokenProvider.resetTokenExpiration(info, new Date().getTime()));
-
- long loginTime = new Date().getTime() + 3600000;
- assertFalse(info.isExpired(loginTime));
- assertTrue(tokenProvider.resetTokenExpiration(info, loginTime));
- }
-
- @Test
public void testCreateTokenWithExpirationParam() throws Exception {
SimpleCredentials sc = new SimpleCredentials(userId, new char[0]);
sc.setAttribute(TokenProvider.PARAM_TOKEN_EXPIRATION, 100000);
@@ -288,35 +233,4 @@ public class TokenProviderImplTest exten
String nodeId = (pos == -1) ? token : token.substring(0, pos);
return new IdentifierManager(root).getTree(nodeId);
}
-
- private final class InvalidTokenInfo implements TokenInfo {
- @Nonnull
- @Override
- public String getUserId() {
- return "invalid";
- }
- @Nonnull
- @Override
- public String getToken() {
- return "invalid";
- }
- @Override
- public boolean isExpired(long loginTime) {
- return true;
- }
- @Override
- public boolean matches(TokenCredentials tokenCredentials) {
- return false;
- }
- @Nonnull
- @Override
- public Map<String, String> getPrivateAttributes() {
- return Collections.emptyMap();
- }
- @Nonnull
- @Override
- public Map<String, String> getPublicAttributes() {
- return Collections.emptyMap();
- }
- }
}
\ No newline at end of file