Spring-security 的 CORS 问题
Posted
技术标签:
【中文标题】Spring-security 的 CORS 问题【英文标题】:CORS problems with Spring-security 【发布时间】:2016-10-30 15:21:45 【问题描述】:我正在使用 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
块(error.status = -1)并且我可以看到控制台中的此错误消息:
XMLHttpRequest 无法加载 http://localhost:8080/api/login。请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin 'http://localhost' 因此不允许访问。
如果我输入了错误的密码,我也会通过以下错误消息到达 catch 块:
XMLHttpRequest 无法加载 http://localhost:8080/api/login。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'http://localhost' 不允许访问。响应的 HTTP 状态代码为 401。
我还注意到,当我调用身份验证端点时,CORS 响应标头丢失了。
有什么想法吗?
编辑:如果我在自定义成功处理程序中手动添加标题,它会起作用。如果 Spring-security 可以考虑全局 CORS 配置,我更愿意。
【问题讨论】:
***.com/questions/35035055/spring-boot-and-cors/… 也许这可以节省您的时间:) 【参考方案1】:有完全相同的问题,你可以做两件事,
@CrossOrigin(origins = "http://localhost:8080")
将此添加到服务方法中。这背后的想法是您通过服务本身启用 CORS 请求。
使用JSONP,但是有一定的限制。我也没有成功实现它,所以我使用了上面的选项。
【讨论】:
【参考方案2】:你应该看看 Spring 网站。有消费网络服务和管理 CORS 的解决方案:
为 RESTful Web 服务启用跨源请求: https://spring.io/guides/gs/rest-service-cors/ 使用 AngularJS 使用 RESTful Web 服务: https://spring.io/guides/gs/consuming-rest-angularjs/【讨论】:
【参考方案3】:根据我的经验,您需要在 CORS 中包含端口号,来自浏览器的错误消息有点误导。
您可以通过检查网络并检查请求标头的 Origin
字段来验证这一点。响应标头的Access-Control-Allow-Origin
中的值必须完全匹配,包括协议和端口。
【讨论】:
以上是关于Spring-security 的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章
Spring-Security OAuth WebMVC 无效的 CORS 请求
如何为 Webflux、Spring-Security、okta-spring-boot-starter 和 Okta-React 正确使用 CORS?