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);

Reply via email to