我有一个spring-boot+spring安全应用程序,在该应用程序中我允许对该应用程序进行CORS(跨域)调用。
我定义了以下弹簧安全配置,
http
.authorizeRequests()
.antMatchers( "/transaction/**").hasRole(SOME_ROLES)
.antMatchers( "/", "/anonymous/pay").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.addFilterBefore(new StatelessLoginFilter(LOGIN_FILTER_URL, tokenAuthenticationService, authenticationManager()), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).maximumSessions(1);
我在下面添加了CORS配置,
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/anonymous/pay")
.allowedOrigins("http://mydomain:8080")
.allowedMethods("PUT", "DELETE", "OPTIONS")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(true).maxAge(3600);
// Add more mappings...
}
}
问题:
当在http://mydomain:8080/anonymous/pay
上从不同的源(跨源)发送请求时,过滤器仍会被调用,而且也没有发送到实际/pay
调用中的标头。值得注意的是,在发送实际请求之前,会从chrome向服务器发送OPTIONS
调用。但是在实际请求中发送的/pay
中缺少标头。一旦StatelessAuthenticationFilter
被触发,HTTP
请求就不携带在/pay
调用中发送的headers
。
有什么见解吗?
最近遇到了这个问题,并找到了解决方案。
当你发送一个跨源请求时,在我使用浏览器的情况下,"reflight">请求会发送到同一个URL,但使用OPTIONAL
http方法和一些头(不包括你添加的头,因此它们丢失了)。
您的SpringSecurity配置拒绝对此飞行前请求的授权,因为它是以这种方式设置的(当然是无意的),并且您得到了403响应。
川苏在这里讨论了这个问题,通过这个问题我找到了这个解决方案。
[EDIT]Robert Schmidt提出了一个SO问题,他已经开始了上面链接的讨论。
基本上,您必须在春季安全配置中将cors().and()
链接到http
,并像一样更改CORS配置
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*") //possibly redundant
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH")
// which ever methods you will be using
.allowedHeaders("Authorization", "Cache-Control", "Content-Type")
// headers that you will be adding to your requests
.allowCredentials(true);
}
如果您通过注入CorsConfigurationSource@Bean来配置CORS,川苏在他的解决方案中提到了它的设置以及上面给出的方法。请务必查看链接。
[EDIT]根据帖子本身,链接到另一个答案,即清洁方法。虽然还没有尝试过,但似乎可以。