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

Spring Security配置迁移至Spring Cloud 2022.0.4的方案咨询

最新Spring Cloud下Spring Security OAuth2资源服务迁移方案

核心问题解答

1. 依赖替换

移除org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure,替换为以下两个核心依赖:

  • org.springframework.boot:spring-boot-starter-oauth2-resource-server:提供OAuth2资源服务核心能力
  • org.springframework.security:spring-security-oauth2-jose:支持JWT格式的令牌解析(如果使用JWT)

Gradle配置示例:

implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.security:spring-security-oauth2-jose'

2. 替代ResourceServerConfigurerAdapter

原类继承的ResourceServerConfigurerAdapter已被弃用,改为使用**@Configuration + @EnableWebSecurity**注解,通过定义SecurityFilterChain Bean来配置HTTP安全规则,同时通过http.oauth2ResourceServer()配置资源服务相关逻辑。

3. 替代OAuth2AuthenticationEntryPoint

原OAuth2AuthenticationEntryPoint被弃用,替换为:

  • 若只需默认异常响应:使用OAuth2AuthorizationExceptionEntryPoint
  • 需自定义响应格式:实现AuthenticationEntryPoint接口,处理OAuth2AuthorizationException等OAuth2相关异常

完整迁移后的代码示例

1. 自定义用户信息转换器适配

原CustomUserDataAuthenticationConverter需要适配新的JWT解析逻辑,改为实现Converter<Jwt, AbstractAuthenticationToken>:

import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;

public class CustomJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {

    private final JwtGrantedAuthoritiesConverter defaultGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();

    @Override
    public AbstractAuthenticationToken convert(Jwt jwt) {
        // 保留原自定义用户信息转换逻辑,比如从JWT Claims中提取用户信息
        var authorities = defaultGrantedAuthoritiesConverter.convert(jwt);
        // 自定义用户主体,比如替换为你的用户实体
        var principal = extractCustomPrincipal(jwt);
        return new JwtAuthenticationToken(jwt, authorities, principal);
    }

    private Object extractCustomPrincipal(Jwt jwt) {
        // 实现原CustomUserDataAuthenticationConverter的用户信息提取逻辑
        return jwt.getClaim("user_id"); // 示例,根据实际Claims调整
    }
}

2. 核心安全配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
@EnableWebSecurity
public class DefaultSecurityConfig {

    private final CustomJwtAuthenticationConverter customJwtAuthenticationConverter;

    // 构造注入替代@Autowired(推荐)
    public DefaultSecurityConfig(CustomJwtAuthenticationConverter customJwtAuthenticationConverter) {
        this.customJwtAuthenticationConverter = customJwtAuthenticationConverter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 无状态会话,符合资源服务特性
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            // 授权规则配置
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/configuration/**").permitAll()
                .anyRequest().authenticated()
            )
            // OAuth2资源服务配置
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt
                    .jwtAuthenticationConverter(customJwtAuthenticationConverter)
                )
                // 自定义认证入口点
                .authenticationEntryPoint(customAuthenticationEntryPoint())
            );

        return http.build();
    }

    // 自定义认证入口点,替代原OAuth2AuthenticationEntryPoint
    @Bean
    public AuthenticationEntryPoint customAuthenticationEntryPoint() {
        return new AuthenticationEntryPoint() {
            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
                // 实现原CustomOAuth2AuthenticationEntryPoint的响应逻辑
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.setContentType("application/json");
                response.getWriter().write("{\"error\": \"Unauthorized\", \"message\": \"Invalid or missing token\"}");
            }
        };
    }
}

3. JWT解析配置(可选,若需自定义签名验证)

如果原代码中使用了NonValidatingAccessTokenConverter(不验证签名),可以通过配置JwtDecoder实现类似逻辑(仅用于测试环境,生产环境必须验证签名):

import org.springframework.context.annotation.Bean;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;

@Bean
public JwtDecoder jwtDecoder() {
    // 不验证签名的Decoder,仅测试用
    return NimbusJwtDecoder.withJwkSetUri("无效地址").build();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 10:37:42