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 <[email protected]> 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);
