我在 Spring 应用程序中添加了安全性,突然遇到了 CORS 问题。我在 Spring 中尝试了许多不同的 CORS 设置(请参阅一些注释掉的代码)。什么都不起作用。
我正在我的前端 Angular 应用程序中传递基本身份验证,如下所示:
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic mybase64basicauth'
})
};
...
this.campaignsSubscription = this.http.get<Campaign[]>(this.campaignsUrl, httpOptions)
我的应用程序在本地和全局都配置为 CrossOrigin。
全局:
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("PUT", "DELETE", "GET", "OPTIONS", "POST", "PATCH")
.allowedHeaders("Authorization", "Content-Type")
// .allowedHeaders("Content-Type")
.allowCredentials(true).maxAge(3600);
// Add more mappings...
}
}
本地:
/*@CrossOrigin(origins = "http://localhost:4200",
allowedHeaders = "*",
methods = { RequestMethod.DELETE, RequestMethod.GET, RequestMethod.HEAD, RequestMethod.OPTIONS, RequestMethod.PATCH, RequestMethod.PUT},
allowCredentials = "true"
)*/
@CrossOrigin
@RestController
@RequestMapping("/api/campaign")
public class CampaignResource {
private CampaignRepository campaignRepository;
public CampaignResource(CampaignRepository campaignRepository) {
this.campaignRepository = campaignRepository;
}
@GetMapping("/all")
public Flux<Campaign> getAll() {
return campaignRepository
.findAll();
...
但我在 Chrome 控制台中收到以下错误:
zone.js:2969 OPTIONS http://localhost:8081/api/campaign/all 401 (Unauthorized)
'http://localhost:8081/api/campaign/all' from origin
'http://localhost:4200' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: No 'Access-
Control-Allow-Origin' header is present on the requested resource.
我知道基本身份验证是正确的,因为它在 Postman 中有效。
最佳答案
使用 Spring Security 5.x 时...
答案有两个:
1) 在您的 SecurityWebFilterChain 中,您必须添加:
.pathMatchers(HttpMethod.OPTIONS, "/**").permitAll()**strong text**
2) 在您的资源中,您必须添加以下 CORS 语句:
@CrossOrigin(origins = "http://localhost:4200",
allowedHeaders = "*",
methods = { RequestMethod.DELETE, RequestMethod.GET, RequestMethod.HEAD, RequestMethod.OPTIONS, RequestMethod.PATCH, RequestMethod.PUT},
allowCredentials = "true"
)
这是我完整的 SecurityConfig 类:
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig {
@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
return http
.authorizeExchange()
.pathMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.pathMatchers("/login", "/logout").permitAll()
.pathMatchers("/i18n/**",
"/css/**",
"/fonts/**",
"/icons-reference/**",
"/img/**",
"/js/**",
"/vendor/**").permitAll()
.pathMatchers(HttpMethod.GET,"/api/**").authenticated()
.anyExchange()
.authenticated()
.and()
.formLogin()
.and()
.httpBasic()
/*.loginPage("/login")
.and()
.logout()
.logoutUrl("/logout")*/
.and()
.csrf().disable()
.build();
}
//in case you want to encrypt password
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
关于spring - 由于 Spring 5 中的 Access/CORS 问题,无法访问后端的 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53289041/