我在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.
我知道基本身份验证是正确的,因为它可以在邮递员中使用。
答案 0 :(得分:2)
使用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();
}
}