You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2019/06/22 03:22:55 UTC

[servicecomb-fence] 07/12: [SCB-1319]refactor code to better satisfy session token & jwt token authentication

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-fence.git

commit d16bba4634bd4c548424b45d994cb799e3949f3b
Author: liubao <bi...@qq.com>
AuthorDate: Mon Jun 17 15:08:29 2019 +0800

    [SCB-1319]refactor code to better satisfy session token & jwt token authentication
---
 .../server/PasswordTokenGranter.java               |  38 +++-----
 .../server/RefreshTokenTokenGranter.java           |  36 ++-----
 .../authentication/server/TokenResponse.java       |  32 +++---
 .../authentication/token/TokenConfiguration.java   |  30 +++---
 .../token/AbstractOpenIDTokenStore.java            |  52 ++++++++++
 .../token/InMemoryOpenIDTokenStore.java            |  51 ++++++++++
 .../token/InMemorySessionIDTokenStore.java         |  42 --------
 .../servicecomb/authentication/token/JWTToken.java |  65 +------------
 .../token/{JWTToken.java => JWTTokenImpl.java}     |   8 +-
 .../authentication/token/JWTTokenStore.java        |  53 +---------
 .../{JWTTokenStore.java => JWTTokenStoreImpl.java} |  22 ++---
 .../authentication/token/OpenIDToken.java          | 108 +++++++++++++++++++++
 .../token/{Token.java => OpenIDTokenStore.java}    |  19 ++--
 ...tSessionIDTokenStore.java => SessionToken.java} |   2 +-
 .../{SessionIDToken.java => SessionTokenImpl.java} |  15 +--
 .../{TokenStore.java => SessionTokenStore.java}    |  11 ++-
 .../servicecomb/authentication/token/Token.java    |   2 +-
 .../authentication/token/TokenStore.java           |   6 +-
 .../servicecomb/authentication/util/Constants.java |  27 ++++++
 .../authentication/edge/AuthHandler.java           |  41 +++++---
 .../authentication/edge/AuthenticationFilter.java  |   6 +-
 ...re.java => DumyEdgeTokenResponseProcessor.java} |  10 +-
 ...yEdgeTokenStore.java => EdgeConfiguration.java} |  26 ++---
 ...nStore.java => EdgeTokenResponseProcessor.java} |   6 +-
 .../authentication/edge/TokenEndpoint.java         |   8 +-
 .../resource/ResourceAuthHandler.java              |  18 ++--
 docs/zh_CN/developersGuide.md                      |  13 +--
 .../AuthenticationConfiguration.java               |  32 +++---
 samples/Client/pom.xml                             |   9 --
 .../authentication/AuthenticationTestCase.java     |  29 +++---
 .../servicecomb/authentication/TestEndpoint.java   |  14 ++-
 .../apache/servicecomb/authentication/TestMgr.java |   4 +-
 .../gateway/AuthenticationConfiguration.java       |  25 ++++-
 .../resource/AuthenticationConfiguration.java      |  14 +--
 34 files changed, 470 insertions(+), 404 deletions(-)

diff --git a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/PasswordTokenGranter.java b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/PasswordTokenGranter.java
index a1538ff..6f893cd 100644
--- a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/PasswordTokenGranter.java
+++ b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/PasswordTokenGranter.java
@@ -19,7 +19,9 @@ package org.apache.servicecomb.authentication.server;
 
 import java.util.Map;
 
-import org.apache.servicecomb.authentication.token.TokenStore;
+import org.apache.servicecomb.authentication.token.AbstractOpenIDTokenStore;
+import org.apache.servicecomb.authentication.token.OpenIDToken;
+import org.apache.servicecomb.authentication.util.Constants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -29,27 +31,19 @@ import org.springframework.stereotype.Component;
 
 import com.netflix.config.DynamicPropertyFactory;
 
-@Component(value = "passwordTokenGranter")
+@Component
 public class PasswordTokenGranter implements TokenGranter {
   @Autowired
-  @Qualifier("authUserDetailsService")
+  @Qualifier(Constants.BEAN_AUTH_USER_DETAILS_SERVICE)
   private UserDetailsService userDetailsService;
 
   @Autowired
-  @Qualifier("authPasswordEncoder")
+  @Qualifier(Constants.BEAN_AUTH_PASSWORD_ENCODER)
   private PasswordEncoder passwordEncoder;
 
   @Autowired
-  @Qualifier("authAccessTokenStore")
-  private TokenStore accessTokenStore;
-
-  @Autowired
-  @Qualifier("authRefreshTokenStore")
-  private TokenStore refreshTokenStore;
-
-  @Autowired
-  @Qualifier("authIDTokenStore")
-  private TokenStore idTokenStore;
+  @Qualifier(Constants.BEAN_AUTH_OPEN_ID_TOKEN_STORE)
+  private AbstractOpenIDTokenStore openIDTokenStore;
 
   @Override
   public TokenResponse grant(Map<String, String> parameters) {
@@ -58,17 +52,9 @@ public class PasswordTokenGranter implements TokenGranter {
 
     UserDetails userDetails = userDetailsService.loadUserByUsername(username);
     if (passwordEncoder.matches(password, userDetails.getPassword())) {
-      TokenResponse token = new TokenResponse();
-      token.setAccess_token(accessTokenStore.createToken(userDetails).getValue());
-      token.setRefresh_token(refreshTokenStore.createToken(userDetails).getValue());
-      token.setId_token(idTokenStore.createToken(userDetails).getValue());
-
-      //TODO add parameters.
-      token.setScope(null);
-      token.setExpires_in(10 * 60);
-      token.setToken_type("bearer");
-
-      return token;
+      OpenIDToken openIDToken = openIDTokenStore.createToken(userDetails);
+      openIDTokenStore.saveToken(openIDToken);
+      return TokenResponse.fromOpenIDToken(openIDToken);
     } else {
       return null;
     }
@@ -82,7 +68,7 @@ public class PasswordTokenGranter implements TokenGranter {
   @Override
   public boolean enabled() {
     return DynamicPropertyFactory.getInstance()
-        .getBooleanProperty("servicecomb.authentication.granter.password.enabled", true)
+        .getBooleanProperty(Constants.CONFIG_GRANTER_PASSWORD_ENABLED, true)
         .get();
   }
 
diff --git a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/RefreshTokenTokenGranter.java b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/RefreshTokenTokenGranter.java
index 6980287..4b0f93f 100644
--- a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/RefreshTokenTokenGranter.java
+++ b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/RefreshTokenTokenGranter.java
@@ -19,8 +19,10 @@ package org.apache.servicecomb.authentication.server;
 
 import java.util.Map;
 
+import org.apache.servicecomb.authentication.token.AbstractOpenIDTokenStore;
+import org.apache.servicecomb.authentication.token.OpenIDToken;
 import org.apache.servicecomb.authentication.token.Token;
-import org.apache.servicecomb.authentication.token.TokenStore;
+import org.apache.servicecomb.authentication.util.Constants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -29,23 +31,15 @@ import org.springframework.stereotype.Component;
 
 import com.netflix.config.DynamicPropertyFactory;
 
-@Component(value = "fefreshTokenTokenGranter")
+@Component
 public class RefreshTokenTokenGranter implements TokenGranter {
   @Autowired
-  @Qualifier("authUserDetailsService")
+  @Qualifier(Constants.BEAN_AUTH_USER_DETAILS_SERVICE)
   private UserDetailsService userDetailsService;
 
   @Autowired
-  @Qualifier("authAccessTokenStore")
-  private TokenStore accessTokenStore;
-
-  @Autowired
-  @Qualifier("authRefreshTokenStore")
-  private TokenStore refreshTokenStore;
-
-  @Autowired
-  @Qualifier("authIDTokenStore")
-  private TokenStore idTokenStore;
+  @Qualifier(Constants.BEAN_AUTH_OPEN_ID_TOKEN_STORE)
+  private AbstractOpenIDTokenStore openIDTokenStore;
 
   @Override
   public boolean enabled() {
@@ -63,22 +57,12 @@ public class RefreshTokenTokenGranter implements TokenGranter {
   public TokenResponse grant(Map<String, String> parameters) {
     String refreshTokenValue = parameters.get(TokenConst.PARAM_REFRESH_TOKEN);
 
-    Token refreshToken = refreshTokenStore.readTokenByValue(refreshTokenValue);
+    Token refreshToken = openIDTokenStore.readTokenByRefreshTokenValue(refreshTokenValue);
 
     if (refreshToken != null && !refreshToken.isExpired()) {
       UserDetails userDetails = userDetailsService.loadUserByUsername(refreshToken.username());
-
-      TokenResponse token = new TokenResponse();
-      token.setAccess_token(accessTokenStore.createToken(userDetails).getValue());
-      // refresh token is not generated 
-      token.setRefresh_token(refreshTokenValue);
-      token.setId_token(idTokenStore.createToken(userDetails).getValue());
-
-      //TODO add parameters.
-      token.setScope(null);
-      token.setExpires_in(10 * 60);
-      token.setToken_type("bearer");
-      return token;
+      OpenIDToken openIDToken = openIDTokenStore.createToken(userDetails);
+      return TokenResponse.fromOpenIDToken(openIDToken);
     }
     return null;
   }
diff --git a/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenResponse.java b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenResponse.java
index 9bdc6d7..32e7fb5 100644
--- a/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenResponse.java
+++ b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenResponse.java
@@ -20,6 +20,8 @@ package org.apache.servicecomb.authentication.server;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.servicecomb.authentication.token.OpenIDToken;
+
 public class TokenResponse {
   // Naming conventions https://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-00#section-3.1
   private String token_type;
@@ -31,13 +33,10 @@ public class TokenResponse {
   // Naming conventions https://openid.net/specs/openid-connect-basic-1_0.html#ObtainingTokens
   private String id_token;
 
-  private int expires_in;
+  private long expires_in;
 
   private Set<String> scope;
 
-  // JWT id
-  private String jti;
-
   private Map<String, Object> additionalInformation;
 
   public String getToken_type() {
@@ -64,11 +63,11 @@ public class TokenResponse {
     this.refresh_token = refresh_token;
   }
 
-  public int getExpires_in() {
+  public long getExpires_in() {
     return expires_in;
   }
 
-  public void setExpires_in(int expires_in) {
+  public void setExpires_in(long expires_in) {
     this.expires_in = expires_in;
   }
 
@@ -88,14 +87,6 @@ public class TokenResponse {
     this.scope = scope;
   }
 
-  public String getJti() {
-    return jti;
-  }
-
-  public void setJti(String jti) {
-    this.jti = jti;
-  }
-
   public Map<String, Object> getAdditionalInformation() {
     return additionalInformation;
   }
@@ -104,4 +95,17 @@ public class TokenResponse {
     this.additionalInformation = additionalInformation;
   }
 
+  public static TokenResponse fromOpenIDToken(OpenIDToken openIDToken) {
+    TokenResponse token = new TokenResponse();
+    token.setAccess_token(openIDToken.getAccessToken().getValue());
+    token.setRefresh_token(openIDToken.getRefreshToken().getValue());
+    token.setId_token(openIDToken.getIdToken().getValue());
+
+    token.setAdditionalInformation(openIDToken.getAdditionalInformation());
+    token.setScope(openIDToken.getScope());
+    token.setExpires_in(openIDToken.getExpiresIn());
+    token.setToken_type(openIDToken.getTokenType());
+
+    return token;
+  }
 }
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java b/api/common/endpoint/src/main/java/org/apache/servicecomb/authentication/token/TokenConfiguration.java
similarity index 55%
copy from samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java
copy to api/common/endpoint/src/main/java/org/apache/servicecomb/authentication/token/TokenConfiguration.java
index e69217f..94b1e21 100644
--- a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java
+++ b/api/common/endpoint/src/main/java/org/apache/servicecomb/authentication/token/TokenConfiguration.java
@@ -15,32 +15,30 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.authentication.resource;
+package org.apache.servicecomb.authentication.token;
 
-import org.apache.servicecomb.authentication.token.JWTTokenStore;
-import org.apache.servicecomb.authentication.token.TokenStore;
+import org.apache.servicecomb.authentication.util.Constants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.security.jwt.crypto.sign.MacSigner;
-import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
+import org.springframework.core.annotation.Order;
 import org.springframework.security.jwt.crypto.sign.Signer;
 import org.springframework.security.jwt.crypto.sign.SignerVerifier;
 
 @Configuration
-public class AuthenticationConfiguration {
-  @Bean(name = {"authSigner", "authSignatureVerifier"})
-  public SignerVerifier authSignerVerifier() {
-    // If using RSA, need to configure authSigner and authSignatureVerifier separately. 
-    // If using MacSigner, need to protect the shared key by properly encryption.
-    return new MacSigner("Please change this key.");
+public class TokenConfiguration {
+  @Bean(name = {Constants.BEAN_AUTH_ACCESS_TOKEN_STORE,
+      Constants.BEAN_AUTH_REFRESH_TOKEN_STORE})
+  @Order(Constants.BEAN_DEFAULT_ORDER)
+  public SessionTokenStore sessionTokenStore() {
+    return new SessionTokenStore();
   }
 
-  @Bean(name = "authIDTokenStore")
-  public TokenStore authIDTokenStore(@Autowired @Qualifier("authSigner") Signer signer,
-      @Autowired @Qualifier("authSignatureVerifier") SignatureVerifier signerVerifier) {
-    return new JWTTokenStore(signer, signerVerifier);
+  @Bean(name = {Constants.BEAN_AUTH_ID_TOKEN_STORE})
+  @Order(Constants.BEAN_DEFAULT_ORDER)
+  public JWTTokenStore jwtTokenStore(@Autowired @Qualifier(Constants.BEAN_AUTH_SIGNER) Signer signer,
+      @Autowired @Qualifier(Constants.BEAN_AUTH_SIGNATURE_VERIFIER) SignerVerifier signerVerifier) {
+    return new JWTTokenStoreImpl(signer, signerVerifier);
   }
-
 }
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/AbstractOpenIDTokenStore.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/AbstractOpenIDTokenStore.java
new file mode 100644
index 0000000..9bc43cf
--- /dev/null
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/AbstractOpenIDTokenStore.java
@@ -0,0 +1,52 @@
+/*
+ * 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.servicecomb.authentication.token;
+
+import org.apache.servicecomb.authentication.util.Constants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.core.userdetails.UserDetails;
+
+public abstract class AbstractOpenIDTokenStore implements OpenIDTokenStore {
+  @Autowired
+  @Qualifier(Constants.BEAN_AUTH_ACCESS_TOKEN_STORE)
+  private TokenStore<SessionToken> accessTokenStore;
+
+  @Autowired
+  @Qualifier(Constants.BEAN_AUTH_REFRESH_TOKEN_STORE)
+  private TokenStore<SessionToken> refreshTokenStore;
+
+  @Autowired
+  @Qualifier(Constants.BEAN_AUTH_ID_TOKEN_STORE)
+  private JWTTokenStore idTokenStore;
+
+  @Override
+  public JWTToken createIDTokenByValue(String jwtTokenValue) {
+    return idTokenStore.createTokenByValue(jwtTokenValue);
+  }
+
+  @Override
+  public OpenIDToken createToken(UserDetails userDetails) {
+    OpenIDToken token = new OpenIDToken();
+    token.setTokenType(Constants.TOKEN_TYPE_BEARER);
+    token.setAccessToken(accessTokenStore.createToken(userDetails));
+    token.setRefreshToken(refreshTokenStore.createToken(userDetails));
+    token.setIdToken(idTokenStore.createToken(userDetails));
+    return token;
+  }
+}
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/InMemoryOpenIDTokenStore.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/InMemoryOpenIDTokenStore.java
new file mode 100644
index 0000000..522e475
--- /dev/null
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/InMemoryOpenIDTokenStore.java
@@ -0,0 +1,51 @@
+/*
+ * 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.servicecomb.authentication.token;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class InMemoryOpenIDTokenStore extends AbstractOpenIDTokenStore {
+  private static final Map<String, OpenIDToken> TOKENS = new ConcurrentHashMap<>();
+
+  private static final Map<String, OpenIDToken> TOKENS_BY_REFRESH_TOKEN_VALUE = new ConcurrentHashMap<>();
+
+  private static final Map<String, OpenIDToken> TOKENS_BY_ID_TOKEN_VALUE = new ConcurrentHashMap<>();
+
+  @Override
+  public OpenIDToken readTokenByValue(String value) {
+    return TOKENS.get(value);
+  }
+
+  @Override
+  public OpenIDToken readTokenByRefreshTokenValue(String refreshTokenValue) {
+    return TOKENS_BY_REFRESH_TOKEN_VALUE.get(refreshTokenValue);
+  }
+
+  @Override
+  public OpenIDToken readTokenByIDTokenValue(String idTokenValue) {
+    return TOKENS_BY_ID_TOKEN_VALUE.get(idTokenValue);
+  }
+
+  @Override
+  public void saveToken(OpenIDToken token) {
+    TOKENS.put(token.getValue(), token);
+    TOKENS_BY_REFRESH_TOKEN_VALUE.put(token.getRefreshToken().getValue(), token);
+    TOKENS_BY_ID_TOKEN_VALUE.put(token.getIdToken().getValue(), token);
+  }
+}
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/InMemorySessionIDTokenStore.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/InMemorySessionIDTokenStore.java
deleted file mode 100644
index 5bac8f0..0000000
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/InMemorySessionIDTokenStore.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.servicecomb.authentication.token;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.security.core.userdetails.UserDetails;
-
-public class InMemorySessionIDTokenStore extends AbstractSessionIDTokenStore {
-  private Map<String, SessionIDToken> tokens = new HashMap<>();
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T extends Token> T createToken(UserDetails userDetails) {
-    SessionIDToken token = new SessionIDToken(userDetails.getUsername());
-    tokens.put(token.getValue(), token);
-    return (T) token;
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T extends Token> T readTokenByValue(String value) {
-    return (T) tokens.get(value);
-  }
-
-}
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTToken.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTToken.java
index e989ae5..a4c6750 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTToken.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTToken.java
@@ -17,69 +17,8 @@
 
 package org.apache.servicecomb.authentication.token;
 
-import java.util.Map;
-
 import org.apache.servicecomb.authentication.jwt.JWTClaims;
-import org.apache.servicecomb.authentication.jwt.JsonParser;
-import org.springframework.security.jwt.Jwt;
-import org.springframework.security.jwt.JwtHelper;
-import org.springframework.security.jwt.crypto.sign.Signer;
-
-public class JWTToken implements Token {
-  private JWTClaims claims;
-
-  private boolean valueCalculated = false;
-
-  private String value;
-
-  private Signer signer;
-
-  public JWTToken(JWTClaims claims, Signer signer) {
-    this.claims = claims;
-    this.signer = signer;
-  }
-
-  @Override
-  public boolean isExpired() {
-    return System.currentTimeMillis() - this.getIssueAt() > this.getExpiration() * 1000;
-  }
-
-  @Override
-  public long getIssueAt() {
-    return this.claims.getIat();
-  }
-
-  @Override
-  public long getExpiration() {
-    return this.claims.getExp();
-  }
-
-  @Override
-  public long getNotBefore() {
-    return this.claims.getNbf();
-  }
-
-  @Override
-  public String getValue() {
-    if (!this.valueCalculated) {
-      String content = JsonParser.unparse(claims);
-      Jwt jwtToken = JwtHelper.encode(content, signer);
-      this.value = jwtToken.getEncoded();
-    }
-    return this.value;
-  }
-
-  @Override
-  public Map<String, Object> getAdditionalInformation() {
-    return this.claims.getAdditionalInformation();
-  }
 
-  @Override
-  public String username() {
-    return this.claims.getSub();
-  }
-  
-  public JWTClaims getClaims() {
-    return this.claims;
-  }
+public interface JWTToken extends Token {
+  public JWTClaims getClaims();
 }
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTToken.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenImpl.java
similarity index 93%
copy from api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTToken.java
copy to api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenImpl.java
index e989ae5..0a99334 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTToken.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenImpl.java
@@ -25,7 +25,7 @@ import org.springframework.security.jwt.Jwt;
 import org.springframework.security.jwt.JwtHelper;
 import org.springframework.security.jwt.crypto.sign.Signer;
 
-public class JWTToken implements Token {
+public class JWTTokenImpl implements JWTToken {
   private JWTClaims claims;
 
   private boolean valueCalculated = false;
@@ -34,14 +34,14 @@ public class JWTToken implements Token {
 
   private Signer signer;
 
-  public JWTToken(JWTClaims claims, Signer signer) {
+  public JWTTokenImpl(JWTClaims claims, Signer signer) {
     this.claims = claims;
     this.signer = signer;
   }
 
   @Override
   public boolean isExpired() {
-    return System.currentTimeMillis() - this.getIssueAt() > this.getExpiration() * 1000;
+    return System.currentTimeMillis() - this.getIssueAt() > this.getExpiresIn() * 1000;
   }
 
   @Override
@@ -50,7 +50,7 @@ public class JWTToken implements Token {
   }
 
   @Override
-  public long getExpiration() {
+  public long getExpiresIn() {
     return this.claims.getExp();
   }
 
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStore.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStore.java
index 2f394e7..67e51cc 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStore.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStore.java
@@ -17,55 +17,6 @@
 
 package org.apache.servicecomb.authentication.token;
 
-import java.util.UUID;
-
-import org.apache.servicecomb.authentication.jwt.JWTClaims;
-import org.apache.servicecomb.authentication.jwt.JsonParser;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.jwt.Jwt;
-import org.springframework.security.jwt.JwtHelper;
-import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
-import org.springframework.security.jwt.crypto.sign.Signer;
-
-public class JWTTokenStore implements TokenStore {
-  private Signer signer;
-
-  private SignatureVerifier signerVerifier;
-
-  public JWTTokenStore(Signer signer, SignatureVerifier signerVerifier) {
-    this.signer = signer;
-    this.signerVerifier = signerVerifier;
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T extends Token> T createToken(UserDetails userDetails) {
-    JWTClaims claims = new JWTClaims();
-    claims.setSub(userDetails.getUsername());
-    if (userDetails.getAuthorities() != null) {
-      userDetails.getAuthorities().forEach(authority -> claims.addAuthority(authority.getAuthority()));
-    }
-
-    // TODO : set other parameters.
-    claims.setJti(UUID.randomUUID().toString());
-    claims.setIat(System.currentTimeMillis());
-    claims.setExp(5 * 60);
-
-    return (T) new JWTToken(claims, signer);
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T extends Token> T readTokenByValue(String value) {
-    Jwt jwt = JwtHelper.decode(value);
-    JWTClaims claims;
-    try {
-      jwt.verifySignature(signerVerifier);
-      claims = JsonParser.parse(jwt.getClaims(), JWTClaims.class);
-    } catch (Exception e) {
-      return null;
-    }
-    return (T) new JWTToken(claims, signer);
-  }
-
+public interface JWTTokenStore extends TokenStore<JWTToken> {
+  public JWTToken createTokenByValue(String value);
 }
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStore.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStoreImpl.java
similarity index 78%
copy from api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStore.java
copy to api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStoreImpl.java
index 2f394e7..f7191c0 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStore.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/JWTTokenStoreImpl.java
@@ -27,19 +27,18 @@ import org.springframework.security.jwt.JwtHelper;
 import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
 import org.springframework.security.jwt.crypto.sign.Signer;
 
-public class JWTTokenStore implements TokenStore {
+public class JWTTokenStoreImpl implements JWTTokenStore {
   private Signer signer;
 
-  private SignatureVerifier signerVerifier;
+  private SignatureVerifier signatureVerifier;
 
-  public JWTTokenStore(Signer signer, SignatureVerifier signerVerifier) {
+  public JWTTokenStoreImpl(Signer signer, SignatureVerifier signatureVerifier) {
     this.signer = signer;
-    this.signerVerifier = signerVerifier;
+    this.signatureVerifier = signatureVerifier;
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <T extends Token> T createToken(UserDetails userDetails) {
+  public JWTToken createToken(UserDetails userDetails) {
     JWTClaims claims = new JWTClaims();
     claims.setSub(userDetails.getUsername());
     if (userDetails.getAuthorities() != null) {
@@ -51,21 +50,18 @@ public class JWTTokenStore implements TokenStore {
     claims.setIat(System.currentTimeMillis());
     claims.setExp(5 * 60);
 
-    return (T) new JWTToken(claims, signer);
+    return new JWTTokenImpl(claims, signer);
   }
 
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T extends Token> T readTokenByValue(String value) {
+  public JWTToken createTokenByValue(String value) {
     Jwt jwt = JwtHelper.decode(value);
     JWTClaims claims;
     try {
-      jwt.verifySignature(signerVerifier);
+      jwt.verifySignature(signatureVerifier);
       claims = JsonParser.parse(jwt.getClaims(), JWTClaims.class);
     } catch (Exception e) {
       return null;
     }
-    return (T) new JWTToken(claims, signer);
+    return new JWTTokenImpl(claims, signer);
   }
-
 }
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDToken.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDToken.java
new file mode 100644
index 0000000..2587619
--- /dev/null
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDToken.java
@@ -0,0 +1,108 @@
+/*
+ * 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.servicecomb.authentication.token;
+
+import java.util.Map;
+import java.util.Set;
+
+public class OpenIDToken implements Token {
+  private String tokenType;
+
+  private SessionToken accessToken;
+
+  private SessionToken refreshToken;
+
+  private JWTToken idToken;
+
+  private Set<String> scope;
+
+  public String getTokenType() {
+    return tokenType;
+  }
+
+  public void setTokenType(String tokenType) {
+    this.tokenType = tokenType;
+  }
+
+  public SessionToken getAccessToken() {
+    return accessToken;
+  }
+
+  public void setAccessToken(SessionToken accessToken) {
+    this.accessToken = accessToken;
+  }
+
+  public SessionToken getRefreshToken() {
+    return refreshToken;
+  }
+
+  public void setRefreshToken(SessionToken refreshToken) {
+    this.refreshToken = refreshToken;
+  }
+
+  public JWTToken getIdToken() {
+    return idToken;
+  }
+
+  public void setIdToken(JWTToken idToken) {
+    this.idToken = idToken;
+  }
+
+  public Set<String> getScope() {
+    return scope;
+  }
+
+  public void setScope(Set<String> scope) {
+    this.scope = scope;
+  }
+
+  @Override
+  public String username() {
+    return accessToken.username();
+  }
+
+  @Override
+  public boolean isExpired() {
+    return accessToken.isExpired();
+  }
+
+  @Override
+  public long getIssueAt() {
+    return accessToken.getIssueAt();
+  }
+
+  @Override
+  public long getExpiresIn() {
+    return accessToken.getExpiresIn();
+  }
+
+  @Override
+  public long getNotBefore() {
+    return accessToken.getNotBefore();
+  }
+
+  @Override
+  public String getValue() {
+    return accessToken.getValue();
+  }
+
+  @Override
+  public Map<String, Object> getAdditionalInformation() {
+    return accessToken.getAdditionalInformation();
+  }
+}
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/Token.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDTokenStore.java
similarity index 71%
copy from api/common/service/src/main/java/org/apache/servicecomb/authentication/token/Token.java
copy to api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDTokenStore.java
index 21b06d5..cd65ead 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/Token.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDTokenStore.java
@@ -17,20 +17,15 @@
 
 package org.apache.servicecomb.authentication.token;
 
-import java.util.Map;
+public interface OpenIDTokenStore extends TokenStore<OpenIDToken> {
 
-public interface Token {
-  String username();
+  OpenIDToken readTokenByValue(String value);
 
-  boolean isExpired();
+  OpenIDToken readTokenByRefreshTokenValue(String refreshTokenValue);
 
-  long getIssueAt();
+  OpenIDToken readTokenByIDTokenValue(String idTokenValue);
+  
+  JWTToken createIDTokenByValue(String jwtTokenValue);
 
-  long getExpiration();
-
-  long getNotBefore();
-
-  String getValue();
-
-  Map<String, Object> getAdditionalInformation();
+  void saveToken(OpenIDToken token);
 }
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/AbstractSessionIDTokenStore.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionToken.java
similarity index 92%
rename from api/common/service/src/main/java/org/apache/servicecomb/authentication/token/AbstractSessionIDTokenStore.java
rename to api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionToken.java
index cb507a3..c39cec4 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/AbstractSessionIDTokenStore.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionToken.java
@@ -17,5 +17,5 @@
 
 package org.apache.servicecomb.authentication.token;
 
-public abstract class AbstractSessionIDTokenStore implements TokenStore {
+public interface SessionToken extends Token {
 }
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionIDToken.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionTokenImpl.java
similarity index 87%
rename from api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionIDToken.java
rename to api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionTokenImpl.java
index 06a6f96..53aa6d0 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionIDToken.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionTokenImpl.java
@@ -20,27 +20,27 @@ package org.apache.servicecomb.authentication.token;
 import java.util.Map;
 import java.util.UUID;
 
-public class SessionIDToken implements Token {
+public class SessionTokenImpl implements SessionToken {
   private String value;
 
   private long issueAt;
 
   // in seconds
-  private long expiration;
+  private long expiresIn;
 
   private String username;
 
-  public SessionIDToken(String username) {
+  public SessionTokenImpl(String username) {
     this.value = UUID.randomUUID().toString();
     this.issueAt = System.currentTimeMillis();
     // TODO add a configuration
-    this.expiration = 600;
+    this.expiresIn = 600;
     this.username = username;
   }
 
   @Override
   public boolean isExpired() {
-    return System.currentTimeMillis() - this.issueAt > this.expiration * 1000;
+    return System.currentTimeMillis() - this.issueAt > this.expiresIn * 1000;
   }
 
   @Override
@@ -49,8 +49,8 @@ public class SessionIDToken implements Token {
   }
 
   @Override
-  public long getExpiration() {
-    return this.expiration;
+  public long getExpiresIn() {
+    return this.expiresIn;
   }
 
   @Override
@@ -70,6 +70,7 @@ public class SessionIDToken implements Token {
     return null;
   }
 
+  @Override
   public String username() {
     return this.username;
   }
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/TokenStore.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionTokenStore.java
similarity index 81%
copy from api/common/service/src/main/java/org/apache/servicecomb/authentication/token/TokenStore.java
copy to api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionTokenStore.java
index 1f26610..59b23aa 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/TokenStore.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/SessionTokenStore.java
@@ -19,8 +19,11 @@ package org.apache.servicecomb.authentication.token;
 
 import org.springframework.security.core.userdetails.UserDetails;
 
-public interface TokenStore {
-  <T extends Token> T createToken(UserDetails userDetails);
-  
-  <T extends Token> T readTokenByValue(String value);
+public class SessionTokenStore implements TokenStore<SessionToken> {
+
+  @Override
+  public SessionToken createToken(UserDetails userDetails) {
+    return new SessionTokenImpl(userDetails.getUsername());
+  }
+
 }
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/Token.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/Token.java
index 21b06d5..29b26db 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/Token.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/Token.java
@@ -26,7 +26,7 @@ public interface Token {
 
   long getIssueAt();
 
-  long getExpiration();
+  long getExpiresIn();
 
   long getNotBefore();
 
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/TokenStore.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/TokenStore.java
index 1f26610..e4b6df1 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/TokenStore.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/TokenStore.java
@@ -19,8 +19,6 @@ package org.apache.servicecomb.authentication.token;
 
 import org.springframework.security.core.userdetails.UserDetails;
 
-public interface TokenStore {
-  <T extends Token> T createToken(UserDetails userDetails);
-  
-  <T extends Token> T readTokenByValue(String value);
+public interface TokenStore<T extends Token> {
+  T createToken(UserDetails userDetails);
 }
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/Constants.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/Constants.java
index 4dcc8e7..43c85b5 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/Constants.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/Constants.java
@@ -22,8 +22,35 @@ public final class Constants {
 
   public static final String CONTEXT_HEADER_AUTHORIZATION = "Authorization";
 
+  public static final String CONTEXT_HEADER_AUTHORIZATION_TYPE = "Authorization-TYPE";
+  
+  public static final String CONTEXT_HEADER_AUTHORIZATION_TYPE_ID_TOKEN = "ID_TOKEN";
+  
+  public static final String CONTEXT_HEADER_AUTHORIZATION_TYPE_SESSION_TOKEN = "SESSION_TOKEN";
+  
   public static final String CONTEXT_HEADER_CLAIMS = "Claims";
 
   public static final String TOKEN_TYPE_BEARER = "Bearer";
 
+  public static final int BEAN_DEFAULT_ORDER = 100;
+
+  public static final String BEAN_AUTH_EDGE_TOKEN_RESPONSE_PROCESSOR = "edgeTokenResponseProcessor";
+
+  public static final String BEAN_AUTH_SIGNER = "authSigner";
+
+  public static final String BEAN_AUTH_SIGNATURE_VERIFIER = "authSignatureVerifier";
+
+  public static final String BEAN_AUTH_PASSWORD_ENCODER = "authPasswordEncoder";
+
+  public static final String BEAN_AUTH_ACCESS_TOKEN_STORE = "authAccessTokenStore";
+
+  public static final String BEAN_AUTH_REFRESH_TOKEN_STORE = "authRefreshTokenStore";
+
+  public static final String BEAN_AUTH_ID_TOKEN_STORE = "authIDTokenStore";
+
+  public static final String BEAN_AUTH_OPEN_ID_TOKEN_STORE = "authOpenIDTokenStore";
+  
+  public static final String BEAN_AUTH_USER_DETAILS_SERVICE = "authUserDetailsService";
+  
+  public static final String CONFIG_GRANTER_PASSWORD_ENABLED = "servicecomb.authentication.granter.password.enabled";
 }
diff --git a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthHandler.java b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthHandler.java
index d209be4..850b733 100644
--- a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthHandler.java
+++ b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthHandler.java
@@ -17,7 +17,10 @@
 
 package org.apache.servicecomb.authentication.edge;
 
-import org.apache.servicecomb.authentication.server.TokenResponse;
+import org.apache.servicecomb.authentication.token.JWTToken;
+import org.apache.servicecomb.authentication.token.JWTTokenStore;
+import org.apache.servicecomb.authentication.token.OpenIDToken;
+import org.apache.servicecomb.authentication.token.OpenIDTokenStore;
 import org.apache.servicecomb.authentication.util.Constants;
 import org.apache.servicecomb.core.Handler;
 import org.apache.servicecomb.core.Invocation;
@@ -25,27 +28,43 @@ import org.apache.servicecomb.foundation.common.utils.BeanUtils;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 
-
 public class AuthHandler implements Handler {
   @Override
   public void handle(Invocation invocation, AsyncResponse asyncResponse) throws Exception {
-    EdgeTokenStore edgeTokenStore = BeanUtils.getBean("authEdgeTokenStore");
-
     String token = invocation.getContext(Constants.CONTEXT_HEADER_AUTHORIZATION);
+    String tokenType = invocation.getContext(Constants.CONTEXT_HEADER_AUTHORIZATION_TYPE);
     if (token == null) {
       asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
       return;
     }
 
-    TokenResponse tokenResonse = edgeTokenStore.readTokenResponse(token);
-    if (tokenResonse == null) {
-      // TODO : check token validity by expiration time
+    if (Constants.CONTEXT_HEADER_AUTHORIZATION_TYPE_ID_TOKEN.equals(tokenType)) {
+      JWTTokenStore jwtTokenStore = BeanUtils.getBean(Constants.BEAN_AUTH_ID_TOKEN_STORE);
+      JWTToken jwtToken = jwtTokenStore.createTokenByValue(token);
+      if (jwtToken == null || jwtToken.isExpired()) {
+        asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
+        return;
+      }
+
+      // send id_token to services to apply state less validation
+      invocation.addContext(Constants.CONTEXT_HEADER_AUTHORIZATION, jwtToken.getValue());
+      invocation.next(asyncResponse);
+    } else if (Constants.CONTEXT_HEADER_AUTHORIZATION_TYPE_SESSION_TOKEN.equals(tokenType)) {
+      OpenIDTokenStore openIDTokenStore = BeanUtils.getBean(Constants.BEAN_AUTH_OPEN_ID_TOKEN_STORE);
+
+
+      OpenIDToken tokenResonse = openIDTokenStore.readTokenByValue(token);
+      if (tokenResonse == null || tokenResonse.isExpired()) {
+        asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
+        return;
+      }
+
+      // send id_token to services to apply state less validation
+      invocation.addContext(Constants.CONTEXT_HEADER_AUTHORIZATION, tokenResonse.getIdToken().getValue());
+      invocation.next(asyncResponse);
+    } else {
       asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
       return;
     }
-
-    // send id_token to services to apply state less validation
-    invocation.addContext(Constants.CONTEXT_HEADER_AUTHORIZATION, tokenResonse.getId_token());
-    invocation.next(asyncResponse);
   }
 }
diff --git a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationFilter.java b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationFilter.java
index 46ba288..6b5b8d7 100644
--- a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationFilter.java
+++ b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationFilter.java
@@ -32,12 +32,16 @@ public class AuthenticationFilter implements HttpServerFilter {
 
   @Override
   public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx requestEx) {
+    // Now support bearer id tokens authentication
+    // TODO : add support for Cookies session tokens. 
     String authentication = requestEx.getHeader(Constants.HTTP_HEADER_AUTHORIZATION);
     if (authentication != null) {
       String[] tokens = authentication.split(" ");
       if (tokens.length == 2) {
-        if (tokens[0].equals("Bearer")) {
+        if (tokens[0].equals(Constants.TOKEN_TYPE_BEARER)) {
           invocation.addContext(Constants.CONTEXT_HEADER_AUTHORIZATION, tokens[1]);
+          invocation.addContext(Constants.CONTEXT_HEADER_AUTHORIZATION_TYPE,
+              Constants.CONTEXT_HEADER_AUTHORIZATION_TYPE_ID_TOKEN);
         }
       }
     }
diff --git a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeTokenStore.java b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/DumyEdgeTokenResponseProcessor.java
similarity index 82%
copy from api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeTokenStore.java
copy to api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/DumyEdgeTokenResponseProcessor.java
index 92bbbaf..97dd3c4 100644
--- a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeTokenStore.java
+++ b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/DumyEdgeTokenResponseProcessor.java
@@ -19,8 +19,12 @@ package org.apache.servicecomb.authentication.edge;
 
 import org.apache.servicecomb.authentication.server.TokenResponse;
 
-public interface EdgeTokenStore {
-  TokenResponse readTokenResponse(String accessTokenValue);
+public class DumyEdgeTokenResponseProcessor implements EdgeTokenResponseProcessor {
+  public DumyEdgeTokenResponseProcessor() {
+  }
+
+  @Override
+  public void process(TokenResponse tokenResponse) {
+  }
 
-  void saveTokenResponse(String accessTokenValue, TokenResponse tokenResponse);
 }
diff --git a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/InMemoryEdgeTokenStore.java b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeConfiguration.java
similarity index 62%
rename from api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/InMemoryEdgeTokenStore.java
rename to api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeConfiguration.java
index 03a7baa..502dc7e 100644
--- a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/InMemoryEdgeTokenStore.java
+++ b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeConfiguration.java
@@ -17,22 +17,16 @@
 
 package org.apache.servicecomb.authentication.edge;
 
-import java.util.HashMap;
-import java.util.Map;
+import org.apache.servicecomb.authentication.util.Constants;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
 
-import org.apache.servicecomb.authentication.server.TokenResponse;
-
-public class InMemoryEdgeTokenStore implements EdgeTokenStore {
-  private Map<String, TokenResponse> tokens = new HashMap<>();
-
-  @Override
-  public TokenResponse readTokenResponse(String accessTokenValue) {
-    return tokens.get(accessTokenValue);
+@Configuration
+public class EdgeConfiguration {
+  @Bean(name = {Constants.BEAN_AUTH_EDGE_TOKEN_RESPONSE_PROCESSOR})
+  @Order(Constants.BEAN_DEFAULT_ORDER)
+  public EdgeTokenResponseProcessor edgeTokenResponseProcessor() {
+    return new DumyEdgeTokenResponseProcessor();
   }
-
-  @Override
-  public void saveTokenResponse(String accessTokenValue, TokenResponse tokenResponse) {
-    tokens.put(accessTokenValue, tokenResponse);
-  }
-
 }
diff --git a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeTokenStore.java b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeTokenResponseProcessor.java
similarity index 84%
rename from api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeTokenStore.java
rename to api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeTokenResponseProcessor.java
index 92bbbaf..09ea7b3 100644
--- a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeTokenStore.java
+++ b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeTokenResponseProcessor.java
@@ -19,8 +19,6 @@ package org.apache.servicecomb.authentication.edge;
 
 import org.apache.servicecomb.authentication.server.TokenResponse;
 
-public interface EdgeTokenStore {
-  TokenResponse readTokenResponse(String accessTokenValue);
-
-  void saveTokenResponse(String accessTokenValue, TokenResponse tokenResponse);
+public interface EdgeTokenResponseProcessor {
+  void process(TokenResponse tokenResponse);
 }
diff --git a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/TokenEndpoint.java b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/TokenEndpoint.java
index 87dcbb0..87f7696 100644
--- a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/TokenEndpoint.java
+++ b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/TokenEndpoint.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 
 import org.apache.servicecomb.authentication.server.TokenResponse;
+import org.apache.servicecomb.authentication.util.Constants;
 import org.apache.servicecomb.provider.pojo.RpcReference;
 import org.apache.servicecomb.provider.rest.common.RestSchema;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -38,9 +39,8 @@ public class TokenEndpoint implements TokenService {
   private AuthenticationServerTokenEndpoint authenticationSererTokenEndpoint;
 
   @Autowired
-  @Qualifier("authEdgeTokenStore")
-  private EdgeTokenStore edgeTokenStore;
-
+  @Qualifier(Constants.BEAN_AUTH_EDGE_TOKEN_RESPONSE_PROCESSOR)
+  private EdgeTokenResponseProcessor edgeTokenResponseProcessor;
 
   @Override
   @PostMapping(path = "/", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@@ -55,7 +55,7 @@ public class TokenEndpoint implements TokenService {
     response.whenComplete((tokenResonse, ex) -> {
       if (!response.isCompletedExceptionally()) {
         result.complete(tokenResonse);
-        edgeTokenStore.saveTokenResponse(tokenResonse.getAccess_token(), tokenResonse);
+        edgeTokenResponseProcessor.process(tokenResonse);
       } else {
         result.completeExceptionally(ex);
       }
diff --git a/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java
index 5c81139..73f0b1a 100644
--- a/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java
+++ b/api/resource-server/service/src/main/java/org/apache/servicecomb/authentication/resource/ResourceAuthHandler.java
@@ -48,25 +48,25 @@ public class ResourceAuthHandler implements Handler {
       return;
     }
 
-    String token = invocation.getContext(Constants.CONTEXT_HEADER_AUTHORIZATION);
-    if (token == null) {
+    String idTokenValue = invocation.getContext(Constants.CONTEXT_HEADER_AUTHORIZATION);
+    if (idTokenValue == null) {
       asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
       return;
     }
     // verify tokens
-    JWTTokenStore store = BeanUtils.getBean("authIDTokenStore");
-    JWTToken t = store.readTokenByValue(token);
-    if(t == null) {
+    JWTTokenStore store = BeanUtils.getBean(Constants.BEAN_AUTH_ID_TOKEN_STORE);
+    JWTToken idToken = store.createTokenByValue(idTokenValue);
+    if (idToken == null) {
       asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
       return;
     }
-    
+
     // check roles
     if (!StringUtils.isEmpty(config.roles)) {
       String[] roles = config.roles.split(",");
       if (roles.length > 0) {
         boolean valid = false;
-        Set<String> authorities = t.getClaims().getAuthorities();
+        Set<String> authorities = idToken.getClaims().getAuthorities();
         for (String role : roles) {
           if (authorities.contains(role)) {
             valid = true;
@@ -81,8 +81,8 @@ public class ResourceAuthHandler implements Handler {
     }
 
     // pre method authentiation
-    Set<GrantedAuthority> grantedAuthorities = new HashSet<>(t.getClaims().getAuthorities().size());
-    t.getClaims().getAuthorities().forEach(v -> grantedAuthorities.add(new SimpleGrantedAuthority(v)));
+    Set<GrantedAuthority> grantedAuthorities = new HashSet<>(idToken.getClaims().getAuthorities().size());
+    idToken.getClaims().getAuthorities().forEach(v -> grantedAuthorities.add(new SimpleGrantedAuthority(v)));
     SecurityContext sc = new SecurityContextImpl();
     Authentication authentication = new SimpleAuthentication(true, grantedAuthorities);
     sc.setAuthentication(authentication);
diff --git a/docs/zh_CN/developersGuide.md b/docs/zh_CN/developersGuide.md
index 3d67833..a681c5a 100644
--- a/docs/zh_CN/developersGuide.md
+++ b/docs/zh_CN/developersGuide.md
@@ -22,16 +22,7 @@ grant_type=password&username=admin&password=changeMyPassword
     "token_type": "bearer",
     "access_token": "SlAV32hkKG",
     "refresh_token": "8xLOxBtZp8",
-    "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
-     yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
-     NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
-     fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
-     AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
-     Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
-     NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
-     QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
-     K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
-     XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg",
+    "id_token": "eyJ...hbGciOiJSU...zI1NiIsImtpZCI6Ij",
     "expires_in": 600,
     "scope": null,
     "jti": null,
@@ -48,7 +39,7 @@ grant_type=password&username=admin&password=changeMyPassword
 
 POST http://localhost:9090/api/resource-server/v1/auth/handler/adminSayHello?name=Hi HTTP/1.1
 Content-Type: application/x-www-form-urlencoded
-Authorization: Bearer czZCaGRSa3F0MzpnWDFmQmF0M2JW
+Authorization: Bearer SlAV32hkKG
 ```
 
   * Edge Service 将 Access Token 转换为对应的 ID Token , 然后将请求转发给Resource Server。
diff --git a/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationConfiguration.java b/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationConfiguration.java
index 20e9f68..49639ff 100644
--- a/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationConfiguration.java
+++ b/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/AuthenticationConfiguration.java
@@ -19,9 +19,9 @@ package org.apache.servicecomb.authentication;
 
 import java.util.Arrays;
 
-import org.apache.servicecomb.authentication.token.InMemorySessionIDTokenStore;
-import org.apache.servicecomb.authentication.token.JWTTokenStore;
-import org.apache.servicecomb.authentication.token.TokenStore;
+import org.apache.servicecomb.authentication.token.AbstractOpenIDTokenStore;
+import org.apache.servicecomb.authentication.token.InMemoryOpenIDTokenStore;
+import org.apache.servicecomb.authentication.util.Constants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
@@ -33,41 +33,33 @@ import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
 import org.springframework.security.jwt.crypto.sign.MacSigner;
-import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
-import org.springframework.security.jwt.crypto.sign.Signer;
 import org.springframework.security.jwt.crypto.sign.SignerVerifier;
 import org.springframework.security.provisioning.InMemoryUserDetailsManager;
 
 @Configuration
 public class AuthenticationConfiguration {
-  @Bean(name = "authPasswordEncoder")
+  @Bean(name = Constants.BEAN_AUTH_PASSWORD_ENCODER)
   public PasswordEncoder authPasswordEncoder() {
     return new Pbkdf2PasswordEncoder();
   }
 
-  @Bean(name = {"authSigner", "authSignatureVerifier"})
+  @Bean(name = {Constants.BEAN_AUTH_SIGNER, Constants.BEAN_AUTH_SIGNATURE_VERIFIER})
   public SignerVerifier authSignerVerifier() {
     // If using RSA, need to configure authSigner and authSignatureVerifier separately. 
     // If using MacSigner, need to protect the shared key by properly encryption.
     return new MacSigner("Please change this key.");
   }
 
-  @Bean(name = {"authAccessTokenStore", "authRefreshTokenStore"})
-  public TokenStore sessionIDTokenStore() {
-    // Use in memory store for testing. Need to implement JDBC or Redis SessionIDTokenStore in product. 
-    return new InMemorySessionIDTokenStore();
+  @Bean(name = Constants.BEAN_AUTH_OPEN_ID_TOKEN_STORE)
+  public AbstractOpenIDTokenStore openIDTokenStore() {
+    // TODO: Use in memory store for testing. Need to implement JDBC or Redis SessionIDTokenStore in product. 
+    return new InMemoryOpenIDTokenStore();
   }
 
-  @Bean(name = "authIDTokenStore")
-  public TokenStore authIDTokenStore(@Autowired @Qualifier("authSigner") Signer signer,
-      @Autowired @Qualifier("authSignatureVerifier") SignatureVerifier signerVerifier) {
-    return new JWTTokenStore(signer, signerVerifier);
-  }
-
-  @Bean(name = "authUserDetailsService")
+  @Bean(name = Constants.BEAN_AUTH_USER_DETAILS_SERVICE)
   public UserDetailsService authUserDetailsService(
-      @Autowired @Qualifier("authPasswordEncoder") PasswordEncoder passwordEncoder) {
-    // Use in memory UserDetails, need to implement JDBC or others in product
+      @Autowired @Qualifier(Constants.BEAN_AUTH_PASSWORD_ENCODER) PasswordEncoder passwordEncoder) {
+    // TODO: Use in memory UserDetails, need to implement JDBC or others in product
     InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
     UserDetails uAdmin = new User("admin", passwordEncoder.encode("changeMyPassword"),
         Arrays.asList(new SimpleGrantedAuthority("ADMIN")));
diff --git a/samples/Client/pom.xml b/samples/Client/pom.xml
index d879756..5bbe9d8 100644
--- a/samples/Client/pom.xml
+++ b/samples/Client/pom.xml
@@ -33,11 +33,6 @@
     <dependencies>
       <dependency>
         <groupId>org.apache.servicecomb.authentication</groupId>
-        <artifactId>authentication-common-api-endpoint</artifactId>
-        <version>0.0.1-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.servicecomb.authentication</groupId>
         <artifactId>authentication-server-api-service</artifactId>
         <version>0.0.1-SNAPSHOT</version>
       </dependency>
@@ -69,10 +64,6 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.servicecomb.authentication</groupId>
-      <artifactId>authentication-common-api-endpoint</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.authentication</groupId>
       <artifactId>authentication-server-api-service</artifactId>
     </dependency>
     <dependency>
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java
index e05545f..eb13bf1 100644
--- a/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/AuthenticationTestCase.java
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.authentication;
 
 import org.apache.servicecomb.authentication.server.TokenResponse;
+import org.apache.servicecomb.authentication.util.Constants;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
@@ -30,16 +31,16 @@ import org.springframework.web.client.HttpClientErrorException;
 public class AuthenticationTestCase implements TestCase {
   @Override
   public void run() {
-    String accessToken = accessToken();
-    testHanlderAuth(accessToken);
-    testMethodAuth(accessToken);
+    String idToken = idToken();
+    testHanlderAuth(idToken);
+    testMethodAuth(idToken);
 
-    accessToken = accessTokenByRefreshToken();
-    testHanlderAuth(accessToken);
-    testMethodAuth(accessToken);
+    idToken = idTokenByRefreshToken();
+    testHanlderAuth(idToken);
+    testMethodAuth(idToken);
   }
 
-  private String accessToken() {
+  private String idToken() {
     // get token
     MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
     map.add("grant_type", "password");
@@ -52,12 +53,12 @@ public class AuthenticationTestCase implements TestCase {
         BootEventListener.edgeServiceTokenEndpoint.postForObject("/",
             new HttpEntity<>(map, headers),
             TokenResponse.class);
-    TestMgr.check("bearer", token.getToken_type());
-    TestMgr.check(true, token.getAccess_token().length() > 10);
-    return token.getAccess_token();
+    TestMgr.check(Constants.TOKEN_TYPE_BEARER, token.getToken_type());
+    TestMgr.check(true, token.getId_token().length() > 10);
+    return token.getId_token();
   }
 
-  private String accessTokenByRefreshToken() {
+  private String idTokenByRefreshToken() {
     // get token
     MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
     map.add("grant_type", "password");
@@ -70,7 +71,7 @@ public class AuthenticationTestCase implements TestCase {
         BootEventListener.edgeServiceTokenEndpoint.postForObject("/",
             new HttpEntity<>(map, headers),
             TokenResponse.class);
-    TestMgr.check("bearer", token.getToken_type());
+    TestMgr.check(Constants.TOKEN_TYPE_BEARER, token.getToken_type());
     TestMgr.check(true, token.getAccess_token().length() > 10);
 
     // refresh token
@@ -83,11 +84,11 @@ public class AuthenticationTestCase implements TestCase {
             new HttpEntity<>(map, headers),
             TokenResponse.class);
     TestMgr.check(token.getToken_type(), tokenNew.getToken_type());
-    TestMgr.check(token.getRefresh_token(), tokenNew.getRefresh_token());
+    TestMgr.check(token.getRefresh_token().equals(tokenNew.getRefresh_token()), false);
     TestMgr.check(token.getAccess_token().equals(tokenNew.getAccess_token()), false);
     TestMgr.check(token.getId_token().equals(tokenNew.getId_token()), false);
 
-    return tokenNew.getAccess_token();
+    return tokenNew.getId_token();
   }
 
   private void testHanlderAuth(String accessToken) {
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java
index 19b0af1..a89f8c2 100644
--- a/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestEndpoint.java
@@ -32,19 +32,25 @@ public class TestEndpoint {
 
   @GetMapping(path = "/start")
   public String start() {
-    tests.forEach(test -> test.run());
+    tests.forEach(test -> {
+      try {
+        test.run();
+      } catch (Throwable e) {
+        TestMgr.failed(e.getMessage(), e);
+      }
+    });
+
+    TestMgr.summary();
 
     List<Throwable> errors = TestMgr.errors();
     if (TestMgr.isSuccess()) {
       return TestMgr.successMessage();
     } else {
-      TestMgr.summary();
-
       StringBuilder sb = new StringBuilder();
       sb.append("Failed count : " + errors.size());
       sb.append("\n");
       errors.forEach(t -> sb.append(t.getMessage() + "\n"));
-      
+
       TestMgr.reset();
       return sb.toString();
     }
diff --git a/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java
index 030bb4c..c9e71fe 100644
--- a/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java
+++ b/samples/Client/src/main/java/org/apache/servicecomb/authentication/TestMgr.java
@@ -71,9 +71,9 @@ public class TestMgr {
   }
 
   public static void failed(String desc, Throwable e) {
-    Error error = new Error(msg + " | " + desc + ", method is " + getCaller());
+    Error error = new Error(msg + " | " + desc + ", method is " + getCaller() + " , error type is " + e.getClass().toString());
     if (e != null) {
-      error.setStackTrace(error.getStackTrace());
+      error.setStackTrace(e.getStackTrace());
     }
     errorList.add(error);
   }
diff --git a/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationConfiguration.java b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationConfiguration.java
index e9187b7..62ab060 100644
--- a/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationConfiguration.java
+++ b/samples/EdgeService/src/main/java/org/apache/servicecomb/authentication/gateway/AuthenticationConfiguration.java
@@ -17,15 +17,30 @@
 
 package org.apache.servicecomb.authentication.gateway;
 
-import org.apache.servicecomb.authentication.edge.EdgeTokenStore;
-import org.apache.servicecomb.authentication.edge.InMemoryEdgeTokenStore;
+import org.apache.servicecomb.authentication.token.JWTTokenStore;
+import org.apache.servicecomb.authentication.token.JWTTokenStoreImpl;
+import org.apache.servicecomb.authentication.util.Constants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.security.jwt.crypto.sign.MacSigner;
+import org.springframework.security.jwt.crypto.sign.Signer;
+import org.springframework.security.jwt.crypto.sign.SignerVerifier;
 
 @Configuration
 public class AuthenticationConfiguration {
-  @Bean(name = "authEdgeTokenStore")
-  public EdgeTokenStore authEdgeTokenStore() {
-    return new InMemoryEdgeTokenStore();
+  @Bean(name = {Constants.BEAN_AUTH_SIGNER, Constants.BEAN_AUTH_SIGNATURE_VERIFIER})
+  public SignerVerifier authSignerVerifier() {
+    // If using RSA, need to configure authSigner and authSignatureVerifier separately. 
+    // If using MacSigner, need to protect the shared key by properly encryption.
+    return new MacSigner("Please change this key.");
   }
+
+  @Bean(name = Constants.BEAN_AUTH_ID_TOKEN_STORE)
+  public JWTTokenStore authIDTokenStore(@Autowired @Qualifier(Constants.BEAN_AUTH_SIGNER) Signer signer, 
+      @Autowired @Qualifier(Constants.BEAN_AUTH_SIGNATURE_VERIFIER) SignerVerifier signerVerifier) {
+    return new JWTTokenStoreImpl(signer, signerVerifier);
+  }
+
 }
diff --git a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java
index e69217f..b1dcb00 100644
--- a/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java
+++ b/samples/ResourceServer/src/main/java/org/apache/servicecomb/authentication/resource/AuthenticationConfiguration.java
@@ -18,29 +18,29 @@
 package org.apache.servicecomb.authentication.resource;
 
 import org.apache.servicecomb.authentication.token.JWTTokenStore;
-import org.apache.servicecomb.authentication.token.TokenStore;
+import org.apache.servicecomb.authentication.token.JWTTokenStoreImpl;
+import org.apache.servicecomb.authentication.util.Constants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.jwt.crypto.sign.MacSigner;
-import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
 import org.springframework.security.jwt.crypto.sign.Signer;
 import org.springframework.security.jwt.crypto.sign.SignerVerifier;
 
 @Configuration
 public class AuthenticationConfiguration {
-  @Bean(name = {"authSigner", "authSignatureVerifier"})
+  @Bean(name = {Constants.BEAN_AUTH_SIGNER, Constants.BEAN_AUTH_SIGNATURE_VERIFIER})
   public SignerVerifier authSignerVerifier() {
     // If using RSA, need to configure authSigner and authSignatureVerifier separately. 
     // If using MacSigner, need to protect the shared key by properly encryption.
     return new MacSigner("Please change this key.");
   }
 
-  @Bean(name = "authIDTokenStore")
-  public TokenStore authIDTokenStore(@Autowired @Qualifier("authSigner") Signer signer,
-      @Autowired @Qualifier("authSignatureVerifier") SignatureVerifier signerVerifier) {
-    return new JWTTokenStore(signer, signerVerifier);
+  @Bean(name = Constants.BEAN_AUTH_ID_TOKEN_STORE)
+  public JWTTokenStore authIDTokenStore(@Autowired @Qualifier(Constants.BEAN_AUTH_SIGNER) Signer signer, 
+      @Autowired @Qualifier(Constants.BEAN_AUTH_SIGNATURE_VERIFIER) SignerVerifier signerVerifier) {
+    return new JWTTokenStoreImpl(signer, signerVerifier);
   }
 
 }