每个令牌的 Spring OAuth2 访问令牌到期时间更新

时间:2021-03-06 16:11:50

标签: java spring spring-boot spring-security oauth-2.0

我有一个授权服务器和多个 OAuth2 资源服务器。所有这些都是使用 Spring Security OAuth2 实现的。我也有使用授权代码流生成令牌的前端客户端。

我的情况是,如果刷新令牌的有效期为 2 小时,而访问令牌的有效期为 1 小时。首先获取令牌没有问题(两个令牌都是新的。1 小时后,访问令牌已过期。现在假设应用程序仅在 30 分钟(1.5 小时过去)后才使用现有刷新令牌重试新的访问令牌,并且生成一个新的访问令牌,有效期为 1 小时,比刷新令牌多 30 分钟。在前端,我将令牌存储在 cookie 中,刷新令牌在 30 分钟后被删除。当我尝试再次使用新鲜获取令牌时身份验证代码流,spring oauth2 服务器返回相同的过期刷新令牌和活动访问令牌。我的应用程序进入了用户是否获得授权的困惑状态,因为即使经过多次重试,它也只有访问令牌。

是否可以生成过期时间始终小于或等于刷新令牌的访问令牌?

2 个答案:

答案 0 :(得分:0)

当您尝试使用新的身份验证代码流时,您应该获得新的 access_tokenrefresh_token。为此,您应该为您的 tokenStore 创建您自己的 AuthenticationKeyGenerator,如前所述 here

答案 1 :(得分:0)

我已经在Token Enhancer中处理过了。我只是得到新生成的访问令牌的到期时间和现有刷新令牌的到期时间。如果访问令牌的到期时间大于刷新令牌的到期时间,则将更新访问令牌的到期时间以刷新令牌的到期时间。下面是我的代码示例。

public class CustomTokenEnhancer implements TokenEnhancer {

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        ExpiringOAuth2RefreshToken refreshToken = ((ExpiringOAuth2RefreshToken)accessToken.getRefreshToken());
        long refreshTokenExpiresIn = ((ExpiringOAuth2RefreshToken)accessToken.getRefreshToken()).getExpiration().getTime();
        long accessTokenExpiresIn = accessToken.getExpiration().getTime();
        LOGGER.info("RT {} and AT {}", refreshTokenExpiresIn, accessTokenExpiresIn);
        if(accessTokenExpiresIn > refreshTokenExpiresIn) {
            ((DefaultOAuth2AccessToken) accessToken).setExpiration(refreshToken.getExpiration());
        }
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInformation);
        return accessToken;
    }

}

以下是在配置中设置 TokenEnhancer 的方法:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration implements AuthorizationServerConfigurer {

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenEnhancer(tokenEnhancer());
    }

}