use*_*270 6 spring-security cors spring-boot
我已经从 Spring Boot 2.5 升级到 3.1,它附带了 Spring Security 6.1.1。对登录身份验证 REST 服务的调用工作正常,但对需要身份验证令牌的其他 REST 控制器的所有请求都被 CORS 策略阻止。
我已按照 Springs 文档中的说明禁用 CORS,但它不起作用。 https://docs.spring.io/spring-security/reference/reactive/integrations/cors.html#page-title
这是我当前的配置:
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOriginPattern("*");
configuration.setAllowedMethods(Arrays.asList("GET","POST","PUT","PATCH","DELETE","OPTIONS"));
configuration.setAllowCredentials(false);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
//.cors(cors -> cors.disable()) <<--- does not work as documented
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(request -> request
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers(SYS_ADMIN_PATTERNS).hasAuthority("SYSTEM_ADMIN")
.requestMatchers("/api/v1/**").authenticated()
)
.sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS))
.authenticationProvider(authenticationProvider())
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用 .cors(cors -> cors.disable()) 设置禁用 CORS,但这并没有禁用 CORS 过滤。
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors.disable())
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(request -> request
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers(SYS_ADMIN_PATTERNS).hasAuthority("SYSTEM_ADMIN")
.requestMatchers("/api/v1/**").authenticated()
)
.sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS))
.authenticationProvider(authenticationProvider())
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
Run Code Online (Sandbox Code Playgroud)
还尝试将 @CrossOrigin 注释标记添加到 REST 控制器类,但什么也没做。还验证了我是否具有 @Configuration 注释和 @EnableWebSecurity 注释(Spring Security 中的另一个更改)。
我缺少什么?
Anm*_*hah 10
经过几天的努力,我得出了一些结论,比如这是如何运作的。
我在预检请求中遇到 401 错误
我遵循了文档代码,因为预检请求导致了问题,我又添加了一个专门针对预检请求的 requestMather
.requestMatchers(HttpMethod.OPTIONS,"/**").permitAll()
Run Code Online (Sandbox Code Playgroud)
并将 @CrossOrigin 添加到类级别的控制器中
我可以让它工作的唯一方法是在 SecurityFilterChain 中禁用 CORS 并使用 @CrossOrigin 注释 RestController。如果您配置了 CorsConfigurationSource,则 @CrossOrigin 注释将被忽略(或至少没有效果),并且它根本无法与 Spring Security 6.1 一起使用。
这是工作配置:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(request -> request
.requestMatchers("/api/auth").permitAll()
.requestMatchers(HttpMethod.OPTIONS).permitAll()
.requestMatchers(SYS_ADMIN_PATTERNS).hasAuthority("SYSTEM_ADMIN")
.requestMatchers("/api/v1/**").authenticated()
)
.sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS))
.authenticationProvider(authenticationProvider())
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
;
SecurityFilterChain chain = http.build();
log.info("Configured security filter chain: {}",chain);
return chain;
}
Run Code Online (Sandbox Code Playgroud)
然后确保在类级别或单个方法级别的 REST 控制器上有 @CrossOrigin 注释。
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
@CrossOrigin
public class AuthenticationController {
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8672 次 |
| 最近记录: |