即使我已经在 Spring boot 中配置了 CORS,我仍然收到此错误 CORS CORS 错误 但它可以与 GET 方法一起使用
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:5173")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("Authorization")
.allowCredentials(true);
}
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/auth/**", "/drive/**").permitAll()
.requestMatchers("/enrollments/**").hasAnyAuthority("LECTURER", "STUDENT")
.requestMatchers(HttpMethod.POST, "/courses/**").hasAuthority("LECTURER")
.requestMatchers(HttpMethod.GET, "/courses/**").hasAnyAuthority("LECTURER", "STUDENT")
.requestMatchers(HttpMethod.POST, "/school/**").hasAuthority("LECTURER")
.requestMatchers(HttpMethod.GET, "/school/**").hasAnyAuthority("LECTURER", "STUDENT")
)
.sessionManagement(manager -> manager.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authenticationProvider())
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
我在React中调用API:
const createNewCourse = async () => {
const res = await axiosInstance.post(
'/courses/new-course',
{
userIds: selectedStudents,
},
{
params: {
title: courseTitle,
lecturerId: user?.userId,
},
withCredentials: true,
}
);
...
};
我已经研究过了,但还是不行。
这是由于 SpringSecurity 拦截了您的
OPTIONS
预检请求,导致 OPTIONS
响应 401
,从而导致 CORS 错误。这是因为 Spring Security 默认使用“拒绝优先”安全策略。
在您的配置中,如果请求未明确匹配任何规则,则应用默认规则:
.anyRequest().authenticated()
您需要稍微修改 SpringSecurity 配置,以便它释放所有预检请求。
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests((auth) -> auth
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // Add this line
.requestMatchers("/auth/**", "/drive/**").permitAll()
.requestMatchers("/enrollments/**").hasAnyAuthority("LECTURER", "STUDENT")
.requestMatchers(HttpMethod.POST, "/courses/**").hasAuthority("LECTURER")
.requestMatchers(HttpMethod.GET, "/courses/**").hasAnyAuthority("LECTURER", "STUDENT")
.requestMatchers(HttpMethod.POST, "/school/**").hasAuthority("LECTURER")
.requestMatchers(HttpMethod.GET, "/school/**").hasAnyAuthority("LECTURER", "STUDENT")
)
.sessionManagement(manager -> manager.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authenticationProvider())
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
这应该可以正常工作。
还有一点你可能要注意的是SpringSecurity的安全配置是基于“同一个Request配置后先生效,后失效”的规则
.requestMatchers( "/**").permitAll()
符合你的所有请求,那么之后的所有配置都将无效。所以你应该采取上面提到的
.authorizeHttpRequests((auth) -> auth
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
将其放在前面以保持高优先级。
如果此解决方案适合您,请考虑将其标记为已接受