2016-06-28 72 views
1

我正在用Spring-boot(在http://localhost:8080)和angular(在http://localhost:80)上构建一个应用程序。弹簧安全的CORS问题

前端和后端代码由2个不同的服务器提供服务。为了避免CORS问题,我过去使用了一个中间的nginx服务器,但我对这个解决方案不再满意。因此,我必须允许CORS。

我允许CORS全球与线:

@Configuration 
public class WebMvcConfiguration extends WebMvcConfigurerAdapter { 

    @Override 
    public void addCorsMappings(CorsRegistry registry) { 
    registry.addMapping("/**") 
     .allowedOrigins("http://localhost") 
     .allowCredentials(true) 
    ; 
    } 
} 

作品为每路线除了认证路线这与春季安全处理:

public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
    http 
     .formLogin() 
     .successHandler(successHandler()) 
     .failureHandler(failureHandler()) 
    //[...] 
    } 

    private AuthenticationSuccessHandler successHandler() { 
    return (httpServletRequest, httpServletResponse, authentication) -> 
     httpServletResponse.setStatus(HttpServletResponse.SC_OK); 
    } 

    private AuthenticationFailureHandler failureHandler() { 
    return (httpServletRequest, httpServletResponse, e) -> { 
     httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
    }; 
} 

这里是在前端部分发送请求的代码:

$http.post('http://localhost:8080/api/login', $.param({'username': username, 'password': password}), 
      {headers: {'content-type': 'application/x-www-form-urlencoded'}} 
).then(function() {}) 
.catch(function(error) {}; 

如果我输入正确的密码,那么http响应代码(我可以在Chrome控制台中看到)是200,但我仍然可以访问catch块(error.status = -1),我可以看到此错误消息在控制台中:

XMLHttpRequest无法加载http://localhost:8080/api/login。请求的资源上没有“Access-Control-Allow-Origin”标题。因此不允许访问原产地'http://localhost'。

如果我输入了错误的密码,我也与此错误消息到达catch块:

的XMLHttpRequest无法加载http://localhost:8080/api/login。请求的资源上没有“Access-Control-Allow-Origin”标题。因此不允许访问原产地'http://localhost'。该响应具有HTTP状态代码401.

我还注意到,当我调用身份验证端点时,CORS响应标头丢失。

任何想法?

编辑:它工作如果我手动添加标头自定义成功处理程序。我宁愿Spring-security可以考虑全局CORS配置。

+0

http://stackoverflow.com/questions/35035055/spring-boot-and-cors/35040051#35040051大概这可以节省您的时间:) –

回答

0

根据我的经验,您需要在CORS中包含端口号,浏览器中的错误消息有点误导。

您可以通过检查网络并检查请求标头的Origin字段来验证。响应头中的值Access-Control-Allow-Origin必须与包含协议和端口的值完全匹配。

0

有完全相同的问题你可以做两件事,

  1. @CrossOrigin(origins = "http://localhost:8080")将此添加到服务方法。这背后的想法是您通过服务本身启用CORS请求。
  2. 使用JSONP,但这有一定的局限性。我也没有成功实施它,所以我使用了上述选项。