HTTP状态403-在请求参数'_csrf'或标头'X-CSRF-TOKEN'上发现无效的CSRF令牌'9ee6949c-c5dc-4d4b-9d55-46b75abc2994' [英] HTTP Status 403 - Invalid CSRF Token '9ee6949c-c5dc-4d4b-9d55-46b75abc2994' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'

查看:165
本文介绍了HTTP状态403-在请求参数'_csrf'或标头'X-CSRF-TOKEN'上发现无效的CSRF令牌'9ee6949c-c5dc-4d4b-9d55-46b75abc2994'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Web应用程序,该应用程序的前端具有angularjs,后端具有spring-security和jersey.

I am developing a web application which has a front-end with angularjs and a back-end with spring-security and jersey.

我正在尝试实施弹簧安全性.我可以验证用户身份.但是我停留在登出点.我正在发送一个值内的X-CSRF-TOKEN,但似乎spring-security拒绝了它.

I am trying to implement spring-security. I can authenticate the user. But I stucked at the logout point. I am sending the X-CSRF-TOKEN within a value, but it seems that spring-security is refusing it.

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>


    <display-name>M2Carros</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext.xml
            classpath:spring-security.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>
            com.sun.jersey.spi.spring.container.servlet.SpringServlet
        </servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>br.com.m2carros</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
            <param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
            <param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

<!--    Spring Security -->
    <filter>
        <filter-name>

    springSecurityFilterChain</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy

</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
        <init-param>
            <param-name>cors.allowed.headers</param-name>
            <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
        </init-param> 
        <init-param>
            <param-name>cors.exposed.headers</param-name>
            <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,X-CSRF-TOKEN</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CorsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

spring-security.xml

spring-security.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <!-- enable use-expressions -->
    <http auto-config="true" use-expressions="true">
        <intercept-url pattern="/" access="permitAll" />
        <intercept-url pattern="/index.html" access="permitAll" />
        <intercept-url pattern="/api/user" access="isAuthenticated()" />
        <!-- enable csrf protection -->
        <csrf/>
    </http>

    <!-- Select users and user_roles from database -->
    <authentication-manager>
        <authentication-provider>
<!--            <password-encoder hash="md5" />  -->
            <jdbc-user-service data-source-ref="dataSource"
                users-by-username-query=
                    "select username,password, enabled from usuario where username=?"
                authorities-by-username-query=
                    "select username, role from user_roles where username =?  " />
        </authentication-provider>
    </authentication-manager>

</beans:beans>

app.js(忽略的路由)

app.js (ommited routes)

$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
    var csrfHeaderName = 'X-CSRF-TOKEN';

    $httpProvider.interceptors.push(function() {
        return {
            response: function(response) {
                console.log(response.headers());
                console.log(response.headers(csrfHeaderName));
                if(response.headers(csrfHeaderName) != null){
                    $httpProvider.defaults.headers.common[csrfHeaderName] = response.headers(csrfHeaderName);
                }
                return response;
            }
        }    
    });

appCtrl.js

appCtrl.js

angular.module('m2App').controller('appCtrl', function($rootScope, $scope, $http, $location){

    var serverUrl = 'http://localhost:8080/m2carros/api';

    var authenticate = function(credentials, callback) {

        var headers = credentials ? {authorization : "Basic "
            + btoa(credentials.username + ":" + credentials.password)
        } : {};

        $http.get(serverUrl+'/user', {headers : headers}).then(function(response) {
          if (response.data.principal != undefined && response.data.principal.username) {
            $rootScope.authenticated = true;
            console.log("is authenticated ? "+$rootScope.authenticated);
          } else {
            $rootScope.authenticated = false;
            console.log("is authenticated ? "+$rootScope.authenticated);
          }
          callback && callback();
        }, function() {
          $rootScope.authenticated = false;
          console.log("is authenticated ? "+$rootScope.authenticated);
          callback && callback();
        });

      }


      authenticate();
      $scope.credentials = {};
      $scope.login = function() {
          authenticate($scope.credentials, function() {
            if ($rootScope.authenticated) {
              $location.path("/");
              console.log("Redirecionando usuario autenticado para /")
              self.error = false;
            } else {
              $location.path("/login");
              self.error = true;
            }
          });
      };

      $rootScope.logout = function() {
          $http.post('logout', {}).then(function() {
            $rootScope.authenticated = false;
            $location.path("/");
          });
        }

});

认证用户

尝试注销

推荐答案

XSRF是一种技术,未经授权的站点可以通过该技术获得用户的 私人数据. Angular提供了一种抵抗XSRF的机制.什么时候 执行XHR请求时,$ http服务从cookie中读取令牌 (默认情况下为XSRF-TOKEN),并将其设置为HTTP标头(X-XSRF-TOKEN).

XSRF is a technique by which an unauthorized site can gain your user's private data. Angular provides a mechanism to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie (by default, XSRF-TOKEN) and sets it as an HTTP header (X-XSRF-TOKEN).

如果您设置了适当的cookie,则可以确保 angular将在内部处理标头

If you set appropriate cookie, then it ensures that angular will take care of the header internally

因此,在这种情况下,您需要检查每个请求的服务器配置都不需要新令牌

So on that case, you need to check that server config won't need a new token each request

提交表单时,您需要发送csrf令牌.您需要在HTML表单中添加以下行:

You need to send the csrf token when you submit your form. You need to add the following line in your HTML form:

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

资源链接:

  1. Spring Rest Service-无效的CSRF令牌当我尝试登录

CodeMed 建议添加

.antMatchers("/send-pin").permitAll()

SecurityConfiguration类中的

.他遇到了一些问题,如下所述:

in SecurityConfiguration class. He got some issue as stated below:

查看Firefox调试工具的网络"标签,其中显示了 与请求一起发送了以下两个cookie: JSESSIONID:"99192501E7CEA0EDEF853BD666AF3C35"和 XSRF-TOKEN:"b50afb87-e15c-4bef-93ca-7c2fdf145fd8",即使 相同请求的服务器日志仍然归结为无效的CSRF 找到 http://localhost:9000/send-pin 的令牌.这导致我 检查为什么发送的令牌被拒绝,几分钟后 我注意到网址格式缺少antmatchers(...),导致 这个答案.

To examine the Network tab of the Firefox debug tools, which showed that the following two cookies were sent with the request: JSESSIONID:"99192501E7CEA0EDEF853BD666AF3C35" and XSRF-TOKEN:"b50afb87-e15c-4bef-93ca-7c2fdf145fd8", even though the server log for the same request still boiled down to Invalid CSRF token found for http://localhost:9000/send-pin . This caused me to examine why the sent token was being rejected, and a few minutes later I noticed the missing antmatchers(...) for the url pattern, leading to this answer.

此更改导致SecurityConfiguration.configure(...)方法现在看起来像:

This change caused SecurityConfiguration.configure(...) method to now look like:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().and().authorizeRequests()
        .antMatchers("/send-pin").permitAll() 
        .antMatchers("/check-pin").permitAll()
        .antMatchers("/index.html", "/", "/login", "/someotherrurl") 
        .permitAll().anyRequest().authenticated().and().csrf()
        .csrfTokenRepository(csrfTokenRepository()).and()
        .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}  

资源链接:

  1. Spring Security-基于令牌的API身份验证&用户/密码验证
  1. How do I send CSRF tokens from AngularJS front end to Spring REST service backend?
  2. Spring Security - Token based API auth & user/password authentication

这篇关于HTTP状态403-在请求参数'_csrf'或标头'X-CSRF-TOKEN'上发现无效的CSRF令牌'9ee6949c-c5dc-4d4b-9d55-46b75abc2994'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆