删除 Spring Security OAuth 2.x 后 Spring Security 5.x 中的 TokenStore

问题描述 投票:0回答:1

Spring Security OAuth 2.x 生命周期结束后,是否计划在 Spring Security 5.x 中提供 TokenStore? 目前我们正在使用 JdbcTokenStore 来缓存令牌,稍后用于代表用户完成长时间运行的进程。

这是当前的应用程序设置:

  • 应用程序正在 Cloud Foundry 中的多个实例上运行
  • 应用程序使用 postgre 作为支持服务
  • 应用程序接收 oauth 令牌
  • 应用程序代表用户,使用令牌来调用云控制器。实际的计算和外部调用可以在不同的应用程序实例上完成。

当前有关代币的流程是:

  1. 应用程序客户端调用一些应用程序实例并触发长时间运行的进程,假设应用程序实例#0被调用。 Oauth 令牌在 API 调用中提供。

  2. #0 上的自定义过滤器(before=“PRE_AUTH_FILTER”)将令牌存储在 JdbcTokenStore 中。
  3. 安全上下文.xml

    <sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /> .... <oauth:resource-server id="resourceServerFilter" resource-id="springsec" token-services-ref="customTokenServices" />

    
    
自定义令牌服务

@Override public OAuth2Authentication loadAuthentication(String tokenString) { // Get an access token for the specified token string OAuth2AccessToken token = readAccessToken(tokenString); // Check if a valid access token has been obtained if (token == null) { logToAuditLogAndThrow("Invalid access token"); } // Check if the token has expired and there is no refresh token if (token.isExpired() && token.getRefreshToken() == null) { tokenStore.removeAccessToken(token); logToAuditLogAndThrow(MessageFormat.format("The access token has expired on {0}", token.getExpiration())); } // Check if an authentication for this token already exists in the token store OAuth2Authentication auth = tokenStore.readAuthentication(token); if (auth == null) { // Create an authentication for the token and store it in the token store TokenProperties tokenProperties = TokenProperties.fromToken(token); auth = SecurityUtil.createAuthentication(tokenProperties.getClientId(), token.getScope(), SecurityUtil.getTokenUserInfo(token)); try { LOGGER.info(MessageFormat.format(Messages.STORING_TOKEN_FOR_USER_0_WITH_EXPIRATION_TIME_1, tokenProperties.getUserName(), token.getExpiresIn())); tokenStore.storeAccessToken(token, auth); } catch (DataIntegrityViolationException e) { LOGGER.debug(Messages.ERROR_STORING_TOKEN_DUE_TO_INTEGRITY_VIOLATION, e); // Ignoring the exception as the token and authentication are already persisted by another client. } } return auth; } @Override public OAuth2AccessToken readAccessToken(String tokenString) { // Check if an access token for the received token string already exists in the token store OAuth2AccessToken token = tokenStore.readAccessToken(tokenString); if (token != null) { LOGGER.debug("Stored token value: " + token.getValue()); LOGGER.debug("Stored token type: " + token.getTokenType()); LOGGER.debug("Stored token expires in: " + token.getExpiresIn()); } else { token = tokenParserChain.parse(tokenString); } return token; }

    #0 上的自定义过滤器(position="LAST")从 JdbcToken 存储中读取令牌并执行一些基本验证,例如过期时间、所需范围等。如果一切正常,则继续。
  1. 安全上下文.xml

    <sec:custom-filter ref="compositeUriAuthorizationFilter" position="LAST" />

  2. 长流程的实际执行开始,其中它被分割成更小的处理步骤。每个处理步骤可以根据负载在不同的应用程序实例上执行。重要的是,所有内容都存储在数据库中,数据库作为单一事实来源。
  3. 注意

    接下来的步骤基本上描述了一步的作用

  4. 处理步骤开始,假设在应用程序实例 #1 上。应用程序搜索 并按启动该进程的用户在 JdbcTokenStore 中查找令牌。过期时间最长的 token 是 get
令牌服务

public OAuth2AccessToken getToken(String userName) { OAuth2AccessToken token = null; Collection<OAuth2AccessToken> tokens = tokenStore.findTokensByUserName(userName); for (OAuth2AccessToken tokenx : tokens) { // If a token is already found, overwrite it if the new token: // 1) has a refresh token, and the current token hasn't, or // 2) expires later than the current token if (token == null || ((tokenx.getRefreshToken() != null) && (token.getRefreshToken() == null)) || (tokenx.getExpiresIn() > token.getExpiresIn())) { token = tokenx; } } return token; }

该令牌用于下次对云控制器的外部调用。
CloudControllerClientProvider

private OAuth2AccessToken getValidToken(String userName) { OAuth2AccessToken token = tokenService.getToken(userName); if (token == null) { throw new SLException(Messages.NO_VALID_TOKEN_FOUND, userName); } if (token.isExpired() && token.getRefreshToken() == null) { tokenService.removeToken(token); throw new SLException(Messages.TOKEN_EXPIRED, userName); } return token; } ... public CloudControllerClient getControllerClient(String userName) { try { return clientFactory.createClient(getValidToken(userName)); } catch (CloudOperationException e) { throw new SLException(e, Messages.CANT_CREATE_CLIENT); } }

最诚挚的问候,
伯彦

java spring-security cloud-foundry spring-security-oauth2
1个回答
0
投票

© www.soinside.com 2019 - 2024. All rights reserved.