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
相关产品推荐
相关产品推荐

