You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用spring-security-oauth2刷新令牌时丢失认证详情问题求助

解决Spring Security OAuth2刷新令牌后丢失OAuth2Authentication详情的问题

我之前也踩过这个一模一样的坑!确实是DefaultTokenServices的refreshAccessToken方法里的默认逻辑有问题——刷新令牌生成新的access_token时,没有把旧令牌关联的OAuth2Authentication中的details字段传递过去,导致刷新后调用OAuth2Authentication.getDetails()拿不到之前的数据,而首次获取的令牌是正常的。

问题根源

默认的refreshAccessToken实现中,会基于刷新令牌重新构建OAuth2Authentication对象,但这个过程只复制了主体信息、权限列表等核心内容,完全忽略了details字段。这个字段通常用来存储客户端IP、请求上下文这类辅助信息,一旦丢失会影响依赖这些数据的业务逻辑。

可行的解决方案

因为官方相关PR一直没合并,而且旧版Spring Security OAuth2已经进入维护状态,最直接的办法就是自定义TokenServices来修复这个问题:

方式一:扩展DefaultTokenServices,手动保留details

重写refreshAccessToken方法,在生成新令牌后,把旧认证对象的details赋值给新的认证对象并重新存储:

import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenRequest;

public class CustomTokenServices extends DefaultTokenServices {

    @Override
    public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest) throws AuthenticationException {
        // 先调用父类方法完成基础刷新逻辑
        OAuth2AccessToken newAccessToken = super.refreshAccessToken(refreshTokenValue, tokenRequest);
        if (newAccessToken == null) {
            return null;
        }

        // 获取旧刷新令牌对应的原始认证信息
        OAuth2Authentication oldAuth = getAuthentication(refreshTokenValue);
        if (oldAuth != null && oldAuth.getDetails() != null) {
            // 获取新access_token对应的认证对象
            OAuth2Authentication newAuth = getAuthentication(newAccessToken.getValue());
            if (newAuth != null) {
                // 复制旧的details到新认证对象
                newAuth.setDetails(oldAuth.getDetails());
                // 重新存储更新后的认证信息
                storeAuthentication(newAuth, newAccessToken);
            }
        }

        return newAccessToken;
    }
}

之后在你的OAuth2配置类里,把这个自定义的CustomTokenServices注入替换默认的DefaultTokenServices即可。

方式二:迁移到Spring Security 5+的OAuth2模块

如果你的项目有升级空间,建议直接迁移到Spring Security 5官方的OAuth2支持(依赖spring-security-oauth2-client和spring-security-oauth2-resource-server)。新版的OAuth2实现已经重构了令牌刷新逻辑,从根本上避免了这类细节丢失的问题,而且官方维护更积极。

关于那个未合并的PR

你提到的那个PR确实是针对这个问题的修复,但因为旧版Spring Security OAuth2已经不再是官方主推的方案(官方转向了Spring Security 5的原生OAuth2支持),所以这类PR大概率不会被合并了。也正因为如此,相关的反馈才比较少——大部分新项目都直接用新版了,老项目遇到问题的可能直接自己动手修复了。

内容的提问来源于stack exchange,提问作者diegocr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:44:30