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/07/12 01:35:31 UTC

[servicecomb-fence] 02/03: [SCB-1365]implements OpenIDStore for edge service

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 01d23ade21287b2ac9f2d1c53fa65f8c543165d2
Author: liubao <bi...@qq.com>
AuthorDate: Thu Jul 11 10:09:57 2019 +0800

    [SCB-1365]implements OpenIDStore for edge service
---
 .../server/RefreshTokenTokenGranter.java           |  2 +-
 .../authentication/server/TokenEndpoint.java       | 24 ++++++++++++-
 .../authentication/server/TokenService.java        |  4 ++-
 .../token/InMemoryOpenIDTokenStore.java            |  9 +++--
 .../authentication/token/OpenIDTokenStore.java     |  6 ++--
 .../authentication/util/CommonConstants.java       | 10 +++---
 api/edge-service/endpoint/pom.xml                  |  5 +++
 .../authentication/edge/AuthHandler.java           | 34 ++++++++++--------
 .../edge/AuthenticationServerTokenEndpoint.java    |  6 +++-
 .../authentication/edge/EdgeOpenIDTokenStore.java  | 40 ++++++++++------------
 .../authentication/edge/TokenEndpoint.java         |  2 +-
 .../authentication/JDBCOpenIDTokenStore.java       | 13 ++++---
 12 files changed, 101 insertions(+), 54 deletions(-)

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 9204dc3..998bb51 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
@@ -62,7 +62,7 @@ public class RefreshTokenTokenGranter implements TokenGranter {
       return null;
     }
 
-    Token refreshToken = openIDTokenStore.readTokenByRefreshTokenValue(refreshTokenValue);
+    Token refreshToken = openIDTokenStore.readTokenByRefreshToken(refreshTokenValue);
 
     if (refreshToken != null && !refreshToken.isExpired()) {
       UserDetails userDetails = userDetailsService.loadUserByUsername(refreshToken.getUsername());
diff --git a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenEndpoint.java b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenEndpoint.java
index bd7f8d8..ee8bbb7 100644
--- a/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenEndpoint.java
+++ b/api/authentication-server/endpoint/src/main/java/org/apache/servicecomb/authentication/server/TokenEndpoint.java
@@ -19,15 +19,22 @@ package org.apache.servicecomb.authentication.server;
 
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.Status;
 
 import org.apache.servicecomb.authentication.token.OpenIDToken;
+import org.apache.servicecomb.authentication.token.OpenIDTokenStore;
+import org.apache.servicecomb.authentication.util.CommonConstants;
 import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 
 @RestSchema(schemaId = "TokenEndpoint")
 @RequestMapping(path = "/v1/token")
@@ -35,9 +42,13 @@ public class TokenEndpoint implements TokenService {
   @Autowired
   private List<TokenGranter> granters;
 
+  @Autowired
+  @Qualifier(CommonConstants.BEAN_AUTH_OPEN_ID_TOKEN_STORE)
+  private OpenIDTokenStore store;
+
   @Override
   @PostMapping(path = "/", consumes = MediaType.APPLICATION_FORM_URLENCODED)
-  public OpenIDToken getToken(@RequestBody Map<String, String> parameters) {
+  public OpenIDToken grantToken(@RequestBody Map<String, String> parameters) {
     String grantType = parameters.get(AuthenticationServerConstants.PARAM_GRANT_TYPE);
 
     for (TokenGranter granter : granters) {
@@ -52,4 +63,15 @@ public class TokenEndpoint implements TokenService {
     return null;
   }
 
+  @Override
+  @PostMapping(path = "/query")
+  public OpenIDToken queryToken(@RequestParam("access_token") String accessToken) {
+    CompletableFuture<OpenIDToken> result = store.readTokenByAccessToken(accessToken);
+    try {
+      return result.get();
+    } catch (Exception e) {
+      throw new InvocationException(Status.INTERNAL_SERVER_ERROR, "internal unexpected error.");
+    }
+  }
+
 }
diff --git a/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenService.java b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenService.java
index 140ef61..2ae3d0f 100644
--- a/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenService.java
+++ b/api/authentication-server/service/src/main/java/org/apache/servicecomb/authentication/server/TokenService.java
@@ -22,5 +22,7 @@ import java.util.Map;
 import org.apache.servicecomb.authentication.token.OpenIDToken;
 
 public interface TokenService {
-  OpenIDToken getToken(Map<String, String> parameters);
+  OpenIDToken grantToken(Map<String, String> parameters);
+
+  OpenIDToken queryToken(String accessToken);
 }
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
index 341f8fd..0458f29 100644
--- 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
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.authentication.token;
 
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -31,12 +32,14 @@ public class InMemoryOpenIDTokenStore extends AbstractOpenIDTokenStore {
   private static final Map<String, OpenIDToken> TOKENS_BY_ID_TOKEN_VALUE = new ConcurrentHashMap<>();
 
   @Override
-  public OpenIDToken readTokenByValue(String value) {
-    return TOKENS.get(value);
+  public CompletableFuture<OpenIDToken> readTokenByAccessToken(String value) {
+    CompletableFuture<OpenIDToken> result = new CompletableFuture<>();
+    result.complete(TOKENS.get(value));
+    return result;
   }
 
   @Override
-  public OpenIDToken readTokenByRefreshTokenValue(String refreshTokenValue) {
+  public OpenIDToken readTokenByRefreshToken(String refreshTokenValue) {
     return TOKENS_BY_REFRESH_TOKEN_VALUE.get(refreshTokenValue);
   }
 
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDTokenStore.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDTokenStore.java
index 4fdf6a2..e767ddd 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDTokenStore.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/token/OpenIDTokenStore.java
@@ -17,11 +17,13 @@
 
 package org.apache.servicecomb.authentication.token;
 
+import java.util.concurrent.CompletableFuture;
+
 public interface OpenIDTokenStore extends TokenStore<OpenIDToken> {
 
-  OpenIDToken readTokenByValue(String value);
+  CompletableFuture<OpenIDToken> readTokenByAccessToken(String accessToken);
 
-  OpenIDToken readTokenByRefreshTokenValue(String refreshTokenValue);
+  OpenIDToken readTokenByRefreshToken(String refreshToken);
 
   JWTToken createIDTokenByValue(String jwtTokenValue);
 
diff --git a/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/CommonConstants.java b/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/CommonConstants.java
index c866e7e..03ee62e 100644
--- a/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/CommonConstants.java
+++ b/api/common/service/src/main/java/org/apache/servicecomb/authentication/util/CommonConstants.java
@@ -18,16 +18,18 @@
 package org.apache.servicecomb.authentication.util;
 
 public final class CommonConstants {
+  public static final String ACCESS_CONTROL_INTERNAL = "INTERNAL";
+
   public static final String HTTP_HEADER_AUTHORIZATION = "Authorization";
 
   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";
@@ -49,6 +51,6 @@ public final class CommonConstants {
   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";
 }
diff --git a/api/edge-service/endpoint/pom.xml b/api/edge-service/endpoint/pom.xml
index 66c4a87..553a17c 100644
--- a/api/edge-service/endpoint/pom.xml
+++ b/api/edge-service/endpoint/pom.xml
@@ -26,6 +26,11 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.servicecomb.authentication</groupId>
+      <artifactId>authentication-common-api-endpoint</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb.authentication</groupId>
       <artifactId>authentication-edge-api-service</artifactId>
       <version>${project.parent.version}</version>
     </dependency>
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 a4b0849..e99e90c 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,8 +17,9 @@
 
 package org.apache.servicecomb.authentication.edge;
 
+import java.util.concurrent.CompletableFuture;
+
 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.CommonConstants;
@@ -38,9 +39,10 @@ public class AuthHandler implements Handler {
       return;
     }
 
+    OpenIDTokenStore openIDTokenStore = BeanUtils.getBean(CommonConstants.BEAN_AUTH_OPEN_ID_TOKEN_STORE);
+
     if (CommonConstants.CONTEXT_HEADER_AUTHORIZATION_TYPE_ID_TOKEN.equals(tokenType)) {
-      JWTTokenStore jwtTokenStore = BeanUtils.getBean(CommonConstants.BEAN_AUTH_ID_TOKEN_STORE);
-      JWTToken jwtToken = jwtTokenStore.createTokenByValue(token);
+      JWTToken jwtToken = openIDTokenStore.createIDTokenByValue(token);
       if (jwtToken == null || jwtToken.isExpired()) {
         asyncResponse.consumerFail(new InvocationException(403, "forbidden", "token expired or not valid."));
         return;
@@ -50,18 +52,22 @@ public class AuthHandler implements Handler {
       invocation.addContext(CommonConstants.CONTEXT_HEADER_AUTHORIZATION, jwtToken.getValue());
       invocation.next(asyncResponse);
     } else if (CommonConstants.CONTEXT_HEADER_AUTHORIZATION_TYPE_SESSION_TOKEN.equals(tokenType)) {
-      // TODO: session based are not fully tested now, just code snippet
-      OpenIDTokenStore openIDTokenStore = BeanUtils.getBean(CommonConstants.BEAN_AUTH_OPEN_ID_TOKEN_STORE);
+      CompletableFuture<OpenIDToken> openIDTokenFuture = openIDTokenStore.readTokenByAccessToken(token);
+      openIDTokenFuture.whenComplete((res, ex) -> {
+        if (openIDTokenFuture.isCompletedExceptionally() || res == null || res.isExpired()) {
+          asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
+          return;
+        }
 
-      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(CommonConstants.CONTEXT_HEADER_AUTHORIZATION, tokenResonse.getIdToken().getValue());
-      invocation.next(asyncResponse);
+        // send id_token to services to apply state less validation
+        invocation.addContext(CommonConstants.CONTEXT_HEADER_AUTHORIZATION, res.getIdToken().getValue());
+        try {
+          invocation.next(asyncResponse);
+        } catch (Exception e) {
+          asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
+          return;
+        }
+      });
     } else {
       asyncResponse.consumerFail(new InvocationException(403, "forbidden", "not authenticated"));
       return;
diff --git a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationServerTokenEndpoint.java b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationServerTokenEndpoint.java
index 18ad3af..9a29c34 100644
--- a/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationServerTokenEndpoint.java
+++ b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/AuthenticationServerTokenEndpoint.java
@@ -24,8 +24,12 @@ import org.apache.servicecomb.authentication.token.OpenIDToken;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
 
 public interface AuthenticationServerTokenEndpoint {
   @PostMapping(path = "/", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
-  public CompletableFuture<OpenIDToken> getToken(@RequestBody Map<String, String> parameters);
+  public CompletableFuture<OpenIDToken> grantToken(@RequestBody Map<String, String> parameters);
+
+  @PostMapping(path = "/query")
+  public CompletableFuture<OpenIDToken> queryToken(@RequestParam("access_token") String accessToken);
 }
diff --git a/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/JDBCOpenIDTokenStore.java b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeOpenIDTokenStore.java
similarity index 55%
copy from samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/JDBCOpenIDTokenStore.java
copy to api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeOpenIDTokenStore.java
index 0163612..8d6348f 100644
--- a/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/JDBCOpenIDTokenStore.java
+++ b/api/edge-service/endpoint/src/main/java/org/apache/servicecomb/authentication/edge/EdgeOpenIDTokenStore.java
@@ -15,44 +15,40 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.authentication;
+package org.apache.servicecomb.authentication.edge;
+
+import java.util.concurrent.CompletableFuture;
 
-import org.apache.servicecomb.authentication.jwt.JsonParser;
 import org.apache.servicecomb.authentication.token.AbstractOpenIDTokenStore;
 import org.apache.servicecomb.authentication.token.OpenIDToken;
-import org.apache.servicecomb.authentication.user.TokenMapper;
 import org.apache.servicecomb.authentication.util.CommonConstants;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.stereotype.Component;
 
 @Component(CommonConstants.BEAN_AUTH_OPEN_ID_TOKEN_STORE)
-public class JDBCOpenIDTokenStore extends AbstractOpenIDTokenStore {
-  @Autowired
-  private TokenMapper tokenMapper;
+public class EdgeOpenIDTokenStore extends AbstractOpenIDTokenStore {
+  @RpcReference(microserviceName = "authentication-server", schemaId = "TokenEndpoint")
+  private AuthenticationServerTokenEndpoint tokenEndpoint;
+
+  @Override
+  public OpenIDToken createToken(UserDetails userDetails) {
+    throw new UnsupportedOperationException();
+  }
 
   @Override
-  public OpenIDToken readTokenByValue(String value) {
-    String tokenInfo = tokenMapper.getTokenInfoByAccessTokenId(value);
-    if (tokenInfo != null) {
-      return JsonParser.parse(tokenInfo, OpenIDToken.class);
-    }
-    return null;
+  public CompletableFuture<OpenIDToken> readTokenByAccessToken(String accessToken) {
+    return tokenEndpoint.queryToken(accessToken);
   }
 
   @Override
-  public OpenIDToken readTokenByRefreshTokenValue(String refreshTokenValue) {
-    String tokenInfo = tokenMapper.getTokenInfoByRefreshTokenId(refreshTokenValue);
-    if (tokenInfo != null) {
-      return JsonParser.parse(tokenInfo, OpenIDToken.class);
-    }
-    return null;
+  public OpenIDToken readTokenByRefreshToken(String refreshToken) {
+    throw new UnsupportedOperationException();
   }
 
   @Override
   public void saveToken(OpenIDToken token) {
-    tokenMapper.insertNewToken(token.getValue(),
-        token.getRefreshToken().getValue(),
-        JsonParser.unparse(token));
+    throw new UnsupportedOperationException();
   }
 
 }
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 ffafe1a..c454f48 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
@@ -40,7 +40,7 @@ public class TokenEndpoint implements TokenService {
     CompletableFuture<TokenResponse> result = new CompletableFuture<>();
 
     CompletableFuture<OpenIDToken> response =
-        authenticationSererTokenEndpoint.getToken(parameters);
+        authenticationSererTokenEndpoint.grantToken(parameters);
     response.whenComplete((tokenResonse, ex) -> {
       if (!response.isCompletedExceptionally()) {
         result.complete(TokenResponse.fromOpenIDToken(tokenResonse));
diff --git a/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/JDBCOpenIDTokenStore.java b/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/JDBCOpenIDTokenStore.java
index 0163612..8382fb1 100644
--- a/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/JDBCOpenIDTokenStore.java
+++ b/samples/AuthenticationServer/src/main/java/org/apache/servicecomb/authentication/JDBCOpenIDTokenStore.java
@@ -17,6 +17,8 @@
 
 package org.apache.servicecomb.authentication;
 
+import java.util.concurrent.CompletableFuture;
+
 import org.apache.servicecomb.authentication.jwt.JsonParser;
 import org.apache.servicecomb.authentication.token.AbstractOpenIDTokenStore;
 import org.apache.servicecomb.authentication.token.OpenIDToken;
@@ -31,16 +33,19 @@ public class JDBCOpenIDTokenStore extends AbstractOpenIDTokenStore {
   private TokenMapper tokenMapper;
 
   @Override
-  public OpenIDToken readTokenByValue(String value) {
+  public CompletableFuture<OpenIDToken> readTokenByAccessToken(String value) {
+    CompletableFuture<OpenIDToken> result = new CompletableFuture<>();
+
     String tokenInfo = tokenMapper.getTokenInfoByAccessTokenId(value);
     if (tokenInfo != null) {
-      return JsonParser.parse(tokenInfo, OpenIDToken.class);
+      result.complete(JsonParser.parse(tokenInfo, OpenIDToken.class));
     }
-    return null;
+    result.complete(null);
+    return result;
   }
 
   @Override
-  public OpenIDToken readTokenByRefreshTokenValue(String refreshTokenValue) {
+  public OpenIDToken readTokenByRefreshToken(String refreshTokenValue) {
     String tokenInfo = tokenMapper.getTokenInfoByRefreshTokenId(refreshTokenValue);
     if (tokenInfo != null) {
       return JsonParser.parse(tokenInfo, OpenIDToken.class);