This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push: new dcc1a86 [SCB-1318]RSAProviderTokenManager#validatedToken expired resource recycling dcc1a86 is described below commit dcc1a868de6b1612dae1c46d6d4935602a2136e5 Author: wuliuqi <247938...@qq.com> AuthorDate: Thu Aug 8 22:06:18 2019 +0800 [SCB-1318]RSAProviderTokenManager#validatedToken expired resource recycling --- .../provider/RSAProviderTokenManager.java | 43 +++++++++++++------ .../TestRSAProviderTokenManager.java | 50 ++++++++++++++++++---- 2 files changed, 71 insertions(+), 22 deletions(-) diff --git a/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/RSAProviderTokenManager.java b/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/RSAProviderTokenManager.java index e0add99..cc42567 100644 --- a/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/RSAProviderTokenManager.java +++ b/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/RSAProviderTokenManager.java @@ -16,13 +16,13 @@ */ package org.apache.servicecomb.authentication.provider; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - +import java.util.concurrent.TimeUnit; import org.apache.servicecomb.authentication.RSAAuthenticationToken; import org.apache.servicecomb.foundation.common.utils.RSAUtils; import org.apache.servicecomb.serviceregistry.api.Const; @@ -35,7 +35,9 @@ public class RSAProviderTokenManager { private final static Logger LOGGER = LoggerFactory.getLogger(RSAProviderTokenManager.class); - private Set<RSAAuthenticationToken> validatedToken = ConcurrentHashMap.newKeySet(1000); + private static Cache<RSAAuthenticationToken, Boolean> validatedToken = CacheBuilder.newBuilder() + .expireAfterAccess(getExpiredTime(), TimeUnit.MILLISECONDS) + .build(); private AccessController accessController = new AccessController(); @@ -46,30 +48,39 @@ public class RSAProviderTokenManager { LOGGER.error("token format is error, perhaps you need to set auth handler at consumer"); return false; } - if (tokenExprired(rsaToken)) { + if (tokenExpired(rsaToken)) { LOGGER.error("token is expired"); return false; } - if (validatedToken.contains(rsaToken)) { + + if (getValidatedToken().asMap().containsKey(rsaToken)) { return accessController.isAllowed(MicroserviceInstanceCache.getOrCreate(rsaToken.getServiceId())); } - String sign = rsaToken.getSign(); - String content = rsaToken.plainToken(); - String publicKey = getPublicKey(rsaToken.getInstanceId(), rsaToken.getServiceId()); - boolean verify = RSAUtils.verify(publicKey, sign, content); - if (verify && !tokenExprired(rsaToken)) { - validatedToken.add(rsaToken); + if (isValidToken(rsaToken) && !tokenExpired(rsaToken)) { + getValidatedToken().put(rsaToken, true); return accessController.isAllowed(MicroserviceInstanceCache.getOrCreate(rsaToken.getServiceId())); } return false; } catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | SignatureException e) { - LOGGER.error("verfiy error", e); + LOGGER.error("verify error", e); return false; } } - private boolean tokenExprired(RSAAuthenticationToken rsaToken) { + public boolean isValidToken(RSAAuthenticationToken rsaToken) + throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException { + String sign = rsaToken.getSign(); + String content = rsaToken.plainToken(); + String publicKey = getPublicKey(rsaToken.getInstanceId(), rsaToken.getServiceId()); + return RSAUtils.verify(publicKey, sign, content); + } + + public static int getExpiredTime() { + return 60 * 60 * 1000; + } + + private boolean tokenExpired(RSAAuthenticationToken rsaToken) { long generateTime = rsaToken.getGenerateTime(); long expired = generateTime + RSAAuthenticationToken.TOKEN_ACTIVE_TIME + 15 * 60 * 1000; long now = System.currentTimeMillis(); @@ -85,4 +96,8 @@ public class RSAProviderTokenManager { return ""; } } + + public static Cache<RSAAuthenticationToken, Boolean> getValidatedToken() { + return validatedToken; + } } diff --git a/handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/TestRSAProviderTokenManager.java b/handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/TestRSAProviderTokenManager.java index 6efbaf9..9e3efcc 100644 --- a/handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/TestRSAProviderTokenManager.java +++ b/handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/TestRSAProviderTokenManager.java @@ -16,9 +16,12 @@ */ package org.apache.servicecomb.authentication; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import java.util.HashMap; import java.util.Map; - +import java.util.concurrent.TimeUnit; +import mockit.Expectations; import org.apache.servicecomb.authentication.consumer.RSAConsumerTokenManager; import org.apache.servicecomb.authentication.provider.RSAProviderTokenManager; import org.apache.servicecomb.config.ConfigUtil; @@ -36,8 +39,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import mockit.Expectations; - public class TestRSAProviderTokenManager { @@ -52,7 +53,7 @@ public class TestRSAProviderTokenManager { } @Test - public void testTokenExpried() { + public void testTokenExpired() { String tokenStr = "e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk="; RSAProviderTokenManager tokenManager = new RSAProviderTokenManager(); @@ -65,14 +66,47 @@ public class TestRSAProviderTokenManager { } @Test - public void testTokenFromVaidatePool() { + @SuppressWarnings("unchecked") + public void testTokenExpiredRemoveInstance() throws Exception { + + String tokenStr = + "e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk="; + RSAAuthenticationToken token = RSAAuthenticationToken.fromStr(tokenStr); + RSAProviderTokenManager tokenManager = new RSAProviderTokenManager(); + new Expectations(RSAProviderTokenManager.class, RSAAuthenticationToken.class) { + { + token.getGenerateTime(); + result = System.currentTimeMillis(); + + tokenManager.isValidToken(token); + result = true; + + RSAProviderTokenManager.getValidatedToken(); + result = CacheBuilder.newBuilder() + .expireAfterAccess(1000, TimeUnit.MILLISECONDS) + .build(); + } + }; + + Assert.assertTrue(tokenManager.valid(tokenStr)); + + Cache<RSAAuthenticationToken, Boolean> cache = RSAProviderTokenManager + .getValidatedToken(); + Assert.assertTrue(cache.asMap().containsKey(token)); + + Thread.sleep(1000); + Assert.assertFalse(cache.asMap().containsKey(token)); + } + + @Test + public void testTokenFromValidatePool() { RSAKeyPairEntry rsaKeyPairEntry = RSAUtils.generateRSAKeyPair(); RSAKeypair4Auth.INSTANCE.setPrivateKey(rsaKeyPairEntry.getPrivateKey()); RSAKeypair4Auth.INSTANCE.setPublicKey(rsaKeyPairEntry.getPublicKey()); RSAKeypair4Auth.INSTANCE.setPublicKeyEncoded(rsaKeyPairEntry.getPublicKeyEncoded()); String serviceId = "c8636e5acf1f11e7b701286ed488fc20"; String instanceId = "e8a04b54cf2711e7b701286ed488fc20"; - RSAConsumerTokenManager rsaCoumserTokenManager = new RSAConsumerTokenManager(); + RSAConsumerTokenManager rsaConsumerTokenManager = new RSAConsumerTokenManager(); MicroserviceInstance microserviceInstance = new MicroserviceInstance(); microserviceInstance.setInstanceId(instanceId); Map<String, String> properties = new HashMap<>(); @@ -90,10 +124,10 @@ public class TestRSAProviderTokenManager { }; //Test Consumer first create token - String token = rsaCoumserTokenManager.getToken(); + String token = rsaConsumerTokenManager.getToken(); Assert.assertNotNull(token); // use cache token - Assert.assertEquals(token, rsaCoumserTokenManager.getToken()); + Assert.assertEquals(token, rsaConsumerTokenManager.getToken()); new Expectations(MicroserviceInstanceCache.class) { { MicroserviceInstanceCache.getOrCreate(serviceId, instanceId);