我们在现有项目中添加了 Spring Security
.
从此刻开始,我们的服务器出现了401 No 'Access-Control-Allow-Origin' header is present on the requested resource
错误 .
那是因为没有 Access-Control-Allow-Origin
标头附加到响应 . 为了解决这个问题,我们在注销过滤器之前添加了我们自己的过滤器,它位于 Filter
链中,但过滤器不适用于我们的请求 .
我们的错误:
XMLHttpRequest无法加载http:// localhost:8080 / getKunden . 请求的资源上不存在“Access-Control-Allow-Origin”标头 . 原因是http:// localhost:3000因此不允许访问 . 响应具有HTTP状态代码401 .
我们的安全配置:
@EnableWebSecurity
@Configuration
@ComponentScan("com.company.praktikant")
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private MyFilter filter;
@Override
public void configure(HttpSecurity http) throws Exception {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
source.registerCorsConfiguration("/**", config);
http.addFilterBefore(new MyFilter(), LogoutFilter.class).authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/*").permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
}
}
我们的滤镜
@Component
public class MyFilter extends OncePerRequestFilter {
@Override
public void destroy() {
}
private String getAllowedDomainsRegex() {
return "individual / customized Regex";
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
final String origin = "http://localhost:3000";
response.addHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers",
"content-type, x-gwt-module-base, x-gwt-permutation, clientid, longpush");
filterChain.doFilter(request, response);
}
}
我们的应用
@SpringBootApplication
public class Application {
public static void main(String[] args) {
final ApplicationContext ctx = SpringApplication.run(Application.class, args);
final AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.register(CORSConfig.class);
annotationConfigApplicationContext.refresh();
}
}
我们的过滤器是从spring-boot注册的:
2016-11-04 09:19:51.494 INFO 9704 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean:映射过滤器:'myFilter'为:[/ *]
我们生成的过滤链:
2016-11-04 09:19:52.729 INFO 9704 --- [ost-startStop-1] ossweb.DefaultSecurityFilterChain:创建过滤链:org.springframework.security.web.util.matcher.AnyRequestMatcher@1,[org .springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter @ 5d8c5a8a,org.springframework.security.web.context.SecurityContextPersistenceFilter @ 7d6938f,org.springframework.security.web.header.HeaderWriterFilter @ 72aa89c,org.springframework.security .web.csrf.CsrfFilter @ 4af4df11,com.company.praktikant.MyFilter @ 5ba65db2,org.springframework.security.web.authentication.logout.LogoutFilter @ 2330834f,org.springframework.security.web.savedrequest.RequestCacheAwareFilter@396532d1,org .springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter @ 4fc0f1a2,org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2357120f,org.springframework.security.web.session.SessionManagementFilter @ 10867bfb,org.springframework.security.web.access .Excepti onTranslationFilter @ 4b8bf1fb,org.springframework.security.web.access.intercept.FilterSecurityInterceptor@42063cf1]
我们从 Spring 天尝试了解决方案,但它没有用!我们控制器中的注释@CrossOrigin也没有帮助 .
编辑1:
尝试了@PiotrSołtysiak的解决方案 . cors过滤器未在生成的过滤器链中列出,我们仍然会得到相同的错误 .
2016-11-04 10:22:49.881 INFO 8820 --- [ost-startStop-1] ossweb.DefaultSecurityFilterChain:创建过滤链:org.springframework.security.web.util.matcher.AnyRequestMatcher@1,[org .springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter @ 4c191377,org.springframework.security.web.context.SecurityContextPersistenceFilter @ 28bad32a,org.springframework.security.web.header.HeaderWriterFilter@3c3ec668,org.springframework.security .web.csrf.CsrfFilter @ 288460dd,org.springframework.security.web.authentication.logout.LogoutFilter @ 1c9cd096,org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@3990c331,org.springframework.security.web.authentication.ui .DefaultLoginPageGeneratingFilter @ 1e8d4ac1,org.springframework.security.web.authentication.www.BasicAuthenticationFilter @ 2d61d2a4,org.springframework.security.web.savedrequest.RequestCacheAwareFilter@380d9a9b,org.springframework.security.web.servletapi.SecurityContextHolderAw areRequestFilter @ abf2de3,org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2a5c161b,org.springframework.security.web.session.SessionManagementFilter@3c1fd3e5,org.springframework.security.web.access.ExceptionTranslationFilter @ 3d7055ef,org.springframework . security.web.access.intercept.FilterSecurityInterceptor@5d27725a]
顺便说一下,我们使用的是spring-security 4.1.3版本 .
8 回答
从Spring Security 4.1开始,这是使Spring Security支持CORS的正确方法(在Spring Boot 1.4 / 1.5中也需要):
和:
不要执行以下任何操作,这是尝试解决问题的错误方法:
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll();
web.ignoring().antMatchers(HttpMethod.OPTIONS);
参考:http://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cors.html
好的,经过2天的搜索,我们终于解决了问题 . 我们删除了所有过滤器和配置,而是在应用程序类中使用了这5行代码 .
@EnableWebSecurity中已经有@Configuration,我无法想象为什么你把@ComponentScan放在那里 .
进入SecurityConfigurationclass和remove配置和配置全局方法 . 您不需要两次设置allowde orgins,headers和方法 . 特别是如果你在过滤器和 spring 安全配置中添加不同的属性:)
根据上述内容,您的“MyFilter”类是多余的 .
你也可以删除那些:
来自Application类 .
http://localhost:8080/getKunden
,您应该在http://localhost:8080/kunden
资源上使用HTTP GET方法 . 您可以在此处了解设计RESTful api的最佳实践:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api由于我遇到其他解决方案的问题(特别是为了让它在所有浏览器中运行,例如edge不能将“*”识别为“Access-Control-Allow-Methods”的有效值),我必须使用自定义过滤组件,它最终为我工作,并完成我想要实现的目标 .
就我而言,我刚刚添加了这个类并使用了@EnableAutConfiguration
}
根据CORS filter documentation:
这样的事情将允许
GET
访问/ajaxUri
:当然,您的SpringSecurity配置必须允许使用列出的方法访问URI . 见@Hendy Irawan回答 .
在很多地方,我看到需要添加此代码的答案:
但在我的情况下,它会抛出一个意外的类类型异常 .
corsFilter()
bean需要CorsFilter
类型,所以我已完成此更改并将bean的这个定义放在我的配置中,现在一切正常 .对于已部署且无法承受代码更改的程序(例如,添加/更新spring安全性),添加简单代理是一种解决方案:https://stackoverflow.com/a/49827300/1758194