【发布时间】:2017-03-18 00:54:17
【问题描述】:
我们在现有项目中添加了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”标头。因此,Originhttp://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.E xceptionTranslationFilter@4b8bf1fb, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@42063cf1]
回应: Response headers
我们也尝试了 spring 的解决方案,但没有奏效!我们控制器中的注解 @CrossOrigin 也没有帮助。
编辑 1:
尝试了@Piotr Soł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.SecurityContextHo lderAwareRequestFilter@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。!
【问题讨论】:
-
Chrome 存在问题,它不支持 localhost 通过 Access-Control-Allow-Origin。换个浏览器试试
-
我们尝试使用 Edge,它可以正常工作...但 Firefox 不能正常工作。
-
我遇到了同样的问题,我通过将
127.0.0.1 localhost local.net添加到/etc/hosts然后调用local.net:8080/getKunden 来解决它 -
请参阅stackoverflow.com/questions/28547288/… 它会有所帮助
标签: java spring spring-security spring-boot cors