Spring Security:如何在OAuth2访问令牌过期前强制获取新令牌
强制Spring Security在Access Token未过期时获取新令牌的方法
方法1:清除已保存的授权客户端记录
通过OAuth2AuthorizedClientService移除当前用户的授权客户端信息,下次发起请求时,Spring Security会重新向授权服务器申请新令牌,不受原有access token是否过期的限制。
代码示例:
@Autowired private OAuth2AuthorizedClientService authorizedClientService; // 调用此方法触发强制刷新 public void triggerForceRefresh(String clientRegistrationId, Authentication authentication) { authorizedClientService.removeAuthorizedClient(clientRegistrationId, authentication.getName()); }
注:该操作会清除已保存的access token和refresh token,若使用授权码模式可能触发重定向授权流程;客户端模式则直接请求新令牌。
方法2:通过OAuth2AuthorizedClientManager主动刷新
利用OAuth2AuthorizedClientManager的refreshToken方法,手动发起令牌刷新请求,无需清除已有记录,直接从授权服务器获取新令牌。
代码示例:
@Autowired private OAuth2AuthorizedClientManager authorizedClientManager; public OAuth2AccessToken getNewAccessToken(String clientRegistrationId, Authentication authentication) { // 构建授权请求 OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId) .principal(authentication) .build(); OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(authorizeRequest); // 主动触发刷新流程 authorizedClient = authorizedClientManager.refreshToken(OAuth2RefreshTokenRequest.withAuthorizedClient(authorizedClient) .principal(authentication) .build()); return authorizedClient.getAccessToken(); }
注:授权服务器通常会返回新的access token,同时可能更新refresh token。
方法3:自定义令牌解析器实现强制刷新
自定义OAuth2AccessTokenResolver,通过标记(比如请求属性、上下文参数)判断是否需要跳过缓存,直接请求授权服务器获取新令牌。
代码示例:
public class ForceRefreshAccessTokenResolver implements OAuth2AccessTokenResolver { private final OAuth2AccessTokenResolver delegateResolver; public ForceRefreshAccessTokenResolver(OAuth2AccessTokenResolver delegateResolver) { this.delegateResolver = delegateResolver; } @Override public OAuth2AccessToken resolve(OAuth2AuthorizationContext context) { // 从上下文获取提前设置的强制刷新标记 Boolean forceRefresh = (Boolean) context.getAttribute("FORCE_REFRESH"); if (Boolean.TRUE.equals(forceRefresh)) { OAuth2AuthorizedClient authorizedClient = context.getAuthorizedClient(); if (authorizedClient != null && authorizedClient.getRefreshToken() != null) { // 返回null让后续流程重新发起令牌请求 return null; } } // 正常走原有令牌解析逻辑 return delegateResolver.resolve(context); } }
之后需将自定义解析器配置到客户端注册配置中,替换默认的令牌解析器。
内容的提问来源于stack exchange,提问作者Godfried
相关产品推荐
相关产品推荐

