Javascript AngularJS XSRF策略不支持cookie路径

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作为

我有三个spring boot应用程序在同一台服务器上以不同的路径运行。所有三个都公开了API端点,其中一个还提供web资源,如
HTML
JavaScript
CSS

应用程序1:

  • 提供用户界面文件
  • 服务于API端点
  • 应用程序2

  • 服务于API端点
  • 应用程序3

  • 服务于API端点
  • 到目前为止,我们只为应用程序1启用了CSRF验证。它与org.springframework.security.web.csrf.CookieCsrfTokenRepository配合得很好。我们将
    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

    我目前的观察结果:

  • 我检查并确保所有三个应用程序都在设置cookies 要成为
    httpOnly=false
  • 我可以看到这三个应用程序都有 他们自己的
    XSRF-TOKEN
    cookie在chrome开发者控制台中 他们自己的道路
  • 我没有在角的一端写一行字 改变它的默认行为
  • 这三个应用程序都作为WAR文件在同一IP和端口上运行
  • 我在这里怀疑的是Angular没有尊重这条道路 属性,并与第一个具有名称的cookie一起使用
    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);
                }
            };
        });
    }]);