Spring-security的CORS问题

时间:2016-06-28 10:35:12

标签: angularjs spring-security spring-boot

我正在构建一个使用Spring-boot(在http://localhost:8080上)和angular(在http://localhost:80上)的应用程序。

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

我允许CORS全局使用这些行:

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {   

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

对于除了使用Spring安全性处理的身份验证路径之外的每条路径,此有效

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块(错误.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配置,我更愿意。

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

你应该看一下Spring网站。有消费Web服务和管理CORS的解决方案:

答案 2 :(得分:0)

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

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