Javascript AngularJS XSRF策略不支持cookie路径
我有三个spring boot应用程序在同一台服务器上以不同的路径运行。所有三个都公开了API端点,其中一个还提供web资源,如Javascript AngularJS XSRF策略不支持cookie路径,javascript,java,angularjs,spring,cookies,Javascript,Java,Angularjs,Spring,Cookies,我有三个spring boot应用程序在同一台服务器上以不同的路径运行。所有三个都公开了API端点,其中一个还提供web资源,如HTML、JavaScript和CSS 应用程序1: 提供用户界面文件 服务于API端点 应用程序2 服务于API端点 应用程序3 服务于API端点 到目前为止,我们只为应用程序1启用了CSRF验证。它与org.springframework.security.web.csrf.CookieCsrfTokenRepository配合得很好。我们将XSRF-TOKEN作为
HTML
、JavaScript
和CSS
应用程序1:
XSRF-TOKEN
作为cookie发送,angularJs在每个请求的头中返回X-XSRF-TOKEN
现在,我们计划将XSRF
引入到其他两个应用程序中,方法与应用程序1相同
但我们遇到了一个问题。AngularJs从应用程序1发送XSRF-TOKEN,并对所有三个应用程序使用相同的TOKEN,而每个应用程序都有自己的TOKEN cookies per(应用程序路径)
这会导致其他两项服务的CSRF
验证失败
以下是我使用的配置
Spring-boot version : 1.5.3
Angular version : 1.3.18
<beans:bean id="csrfTokenRepository" class="org.springframework.security.web.csrf.CookieCsrfTokenRepository">
<beans:property name="cookieHttpOnly" value="false" />
</beans:bean>
这里的令牌2fa60cb2-803f-4b2b-a1d6-7e10e56ca649
来自具有cookie路径/application1的application1
我目前的观察结果:
httpOnly=false
李>
XSRF-TOKEN
cookie在chrome开发者控制台中
他们自己的道路李>
XSRF-TOKEN
有办法解决这个问题吗?您必须更改Angularjs和Spring的默认行为 在SpringSecurity上,您应该更改xrsft cookie名称(3个应用程序各有一个)
在Angular上,您可以在每个请求上添加一个拦截器,该拦截器在头中动态设置正确的cookie值(通过
$cookies.get(key)
检索) 我通过更改所有三个应用程序上的csrfTokenRepository
定义以及AngularJs
中的拦截器,根据请求url
读取这些cookie
,并将所有cookie设置为相同的路径,从而解决了问题
<beans:bean id="csrfTokenRepository"
class="org.springframework.security.web.csrf.CookieCsrfTokenRepository">
<beans:property name="cookieHttpOnly" value="false" />
<beans:property name="cookiePath" value="/" />
<beans:property name="cookieName" value="APP-1-XSRF-TOKEN" />
<beans:property name="headerName" value="APP-1-X-XSRF-TOKEN" />
</beans:bean>
如果您需要进一步的详细信息,请告诉我。有没有一种方法可以不使用不同的xsrf cookie名称来完成此操作…?cookie是单个键/值对。如果您不想更改服务器端cookie名称。您始终可以通过在所有响应上添加拦截器来创建客户端cookie。对于我知道的cookie,有一些属性,如httpOnly
、secure
和path
。。。当您在chrome开发工具中打开应用程序选项卡的Cookie部分时,也可以看到同样的情况
<beans:bean id="csrfTokenRepository"
class="org.springframework.security.web.csrf.CookieCsrfTokenRepository">
<beans:property name="cookieHttpOnly" value="false" />
<beans:property name="cookiePath" value="/" />
<beans:property name="cookieName" value="APP-1-XSRF-TOKEN" />
<beans:property name="headerName" value="APP-1-X-XSRF-TOKEN" />
</beans:bean>
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push(function ($q) {
return {
'request': function (config) {
var readCookie = function (k, r) {
return (r = RegExp('(^|; )' + encodeURIComponent(k) + '=([^;]*)').exec(document.cookie)) ? r[2] : null; //CafePasta from https://stackoverflow.com/a/5639455/2557818
};
if (config.url.indexOf("/app1") > 0) {
config.headers['APP-1-X-XSRF-TOKEN'] = readCookie("APP-1-XSRF-TOKEN", document.cookie);
} else if (config.url.indexOf("/app2") > 0) {
config.headers['APP-2-X-XSRF-TOKEN'] = readCookie("APP-2-XSRF-TOKEN", document.cookie);
} else if (config.url.indexOf("/app3") > 0) {
config.headers['APP-3-X-XSRF-TOKEN'] = readCookie("APP-3-XSRF-TOKEN", document.cookie);
}
return config || $q.when(config);
}
};
});
}]);