我正在构建一个使用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配置,我更愿意。
答案 0 :(得分:0)
根据我的经验,您需要在CORS中包含端口号,来自浏览器的错误消息有点误导。
您可以通过检查网络并检查请求标头的Origin
字段来验证这一点。响应标头的Access-Control-Allow-Origin
中的值必须与包含协议和端口的值完全匹配。
答案 1 :(得分:0)
你应该看一下Spring网站。有消费Web服务和管理CORS的解决方案:
答案 2 :(得分:0)
完全相同的问题你可以做两件事,
@CrossOrigin(origins = "http://localhost:8080")
将此添加到服务方法中。这背后的想法是通过您的服务本身启用CORS请求。