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

升级Spring Security后OAuth2Authentication类缺失问题修复咨询

问题:JDK17+Spring Boot2.7升级后OAuth2认证相关类找不到的修复方案

问题描述

将项目从JDK11升级至JDK17,同步把Spring Boot版本从2.1.6.RELEASE更新到2.7.18,导致spring-security-oauth2-client和spring-security-oauth2-resource-server依赖升级到5.7.11。编译时出现OAuth2Authentication、OAuth2AuthenticationDetails类找不到的问题,原获取token的代码逻辑失效。尝试替换为OAuth2AuthenticationToken和JwtAuthenticationToken的逻辑仍报错,求修复方案。

原代码

public static AuthenticatePerson getPerson(){
        String token = null;
        var person = new AuthenticatePerson();

        Authentication principal = SecurityContextHolder.getContext()
                .getAuthentication();
        if (principal instanceof OAuth2Authentication){
            OAuth2Authentication authentication = (OAuth2Authentication) principal;
            Object details = authentication.getDetails();

            if (details instanceof OAuth2AuthenticationDetails) {
                OAuth2AuthenticationDetails oauthsDetails = (OAuth2AuthenticationDetails) details;
                token = oauthsDetails.getTokenValue();
            }
        }

        try {
            DecodedJWT jwt = JWT.decode(token);
            person.setName(jwt.getClaims().get("name").asString());
            person.setEmail(jwt.getClaims().get("mail").asString());
            person.setGroupe(jwt.getClaims().get("Group").asString());

        } catch (JWTDecodeException exception){
            //Invalid token
        }

        return  person;
    }

尝试的代码

if (principal instanceof OAuth2AuthenticationToken){
            OAuth2AuthenticationToken authenticationToken = (OAuth2AuthenticationToken) principal;
            token = authenticationToken.getAuthorizedClientRegistrationId();
        }
if (principal instanceof JwtAuthenticationToken) {
            JwtAuthenticationToken jwtAuth = (JwtAuthenticationToken) principal;
            token = jwtAuth.getToken().getTokenValue();
        }

修复方案

1. 明确项目的OAuth2角色

Spring Security 5.x彻底重构了OAuth2的API,旧的OAuth2Authentication、OAuth2AuthenticationDetails已被移除,替代方案分两种核心场景:OAuth2资源服务器(接收并验证JWT令牌)和OAuth2客户端(持有令牌调用第三方服务),需根据项目实际角色选择对应逻辑。

2. 资源服务器场景(接收JWT令牌)

如果你的项目是资源服务器,SecurityContext中的Authentication是JwtAuthenticationToken,Spring Security已经完成了JWT的解析,直接使用已解析的数据即可,无需手动解码:

public static AuthenticatePerson getPerson(){
    AuthenticatePerson person = new AuthenticatePerson();
    Authentication principal = SecurityContextHolder.getContext().getAuthentication();

    if (principal instanceof JwtAuthenticationToken jwtAuth) {
        // 获取token字符串
        String token = jwtAuth.getToken().getTokenValue();
        // 直接从已解析的Jwt对象提取Claims,避免手动解码的异常
        Jwt jwt = jwtAuth.getToken();
        person.setName(jwt.getClaimAsString("name"));
        person.setEmail(jwt.getClaimAsString("mail"));
        person.setGroupe(jwt.getClaimAsString("Group"));
    }

    return person;
}

3. OAuth2客户端场景(持有令牌调用第三方服务)

如果你的项目是OAuth2客户端,SecurityContext中的Authentication是OAuth2AuthenticationToken,但该对象本身不存储token,需要通过OAuth2AuthorizedClientService获取授权客户端来拿到token:
首先注入授权客户端服务:

@Autowired
private OAuth2AuthorizedClientService authorizedClientService;

然后修改获取逻辑:

public AuthenticatePerson getPerson(){
    AuthenticatePerson person = new AuthenticatePerson();
    Authentication principal = SecurityContextHolder.getContext().getAuthentication();

    if (principal instanceof OAuth2AuthenticationToken authToken) {
        // 根据客户端ID和用户名加载已授权的客户端
        OAuth2AuthorizedClient authorizedClient = authorizedClientService.loadAuthorizedClient(
                authToken.getAuthorizedClientRegistrationId(),
                authToken.getName()
        );
        if (authorizedClient != null) {
            // 获取token字符串
            String token = authorizedClient.getAccessToken().getTokenValue();
            // 解码JWT获取Claims(如果业务需要)
            try {
                DecodedJWT jwt = JWT.decode(token);
                person.setName(jwt.getClaims().get("name").asString());
                person.setEmail(jwt.getClaims().get("mail").asString());
                person.setGroupe(jwt.getClaims().get("Group").asString());
            } catch (JWTDecodeException exception){
                // 处理无效token的业务逻辑
            }
        }
    }

    return person;
}

4. 依赖检查

确保项目引入了正确的Spring Security OAuth2依赖:

  • 资源服务器依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
  • OAuth2客户端依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:06:00