首页 文章

Spring Security CSRF令牌不在同一个JSP中使用AJAX调用和表单提交

提问于
浏览
3

我试图通过下面的链接在我的项目中实现spring security(ver 3.2.3)CSRF令牌

http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#csrf http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag

我能够在没有AJAX调用的情况下成功地在JSP中集成CSRF令牌 . 但是,当我尝试使用AJAX调用JSP时,获得“无效的CSRF令牌异常” . 在我的分析之后,我找到了使用相同令牌的AJAX调用和表单提交,因为我得到了“无效的CSRF令牌异常” .

可以请任何人帮我突袭这个问题 . 有没有办法生成两个令牌,即一个用于AJAX调用,一个用于表单提交

security.xml文件

<access-denied-handler ref="accessDenied" />

    <intercept-url pattern="/**"  access="ROLE_1" />

    <form-login  default-target-url='/loginUser.htm' always-use-default-target='true' authentication-failure-url='/forms/common/login.jsp?error=true' />

    <logout logout-success-url="/forms/common/logout.jsp" invalidate-session="true" delete-cookies="JSESSIONID" />

    <session-management invalid-session-url="/forms/common/sessionexpired.jsp" session-authentication-error-url="/forms/common/login.jsp?Error=alreadyLoggedin" >

        <concurrency-control expired-url="/forms/common/sessionexpired.jsp" max-sessions="1" error-if-maximum-exceeded="true" />

    </session-management>

    <csrf request-matcher-ref="csrfSecurityRequestMatcher"/>
</http>

<beans:bean class="com.concerto.pg.login.security.CsrfSecurityRequestMatcher" id="csrfSecurityRequestMatcher"/>

JSP

<head>

<sec:csrfMetaTags />

<script type="text/javascript" charset="utf-8">

function changeList(id,option){ 

    var csrfParameter = $("meta[name='_csrf_parameter']").attr("content");
    var csrfToken = $("meta[name='_csrf']").attr("content"); 

    var institution = document.getElementById("institutionId").value; 
    var data = {};

    data[csrfParameter] = csrfToken;
    data["institutionId"] = option;

 if(id=="institutionId"){

    var result ='';

               $.ajax({
                     type: "GET",
                     async: false,
                      url: './getMerchantByInstitution.htm',
                     data: data,//"institutionId=" + option,
                     dataType:'json',
                     success: function (res) {
                     result = res;     
                         var htmlVar = '';
                            for (var i=0; i<result.length; i++){
                                htmlVar += '<option 
                                value="'+result[i]+'">'+result[i]+'</option>';                              
                            }
                            htmlVar += '<option value="ALL">ALL</option>';
                             $('#merchantId').html(htmlVar);
                     }
                 }); 



    }

}

</script>
</head>
added below < input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> statement in form tag

感谢和问候,西瓦

3 回答

  • 1

    我希望以下答案有所帮助 . 进行这些更改

    var csrfParameter = $("meta[name='_csrf_parameter']").attr("content");
    var csrfToken = $("meta[name='_csrf']").attr("content"); 
    var csrfHeader = $("meta[name='_csrf_header']").attr("content");  // THIS WAS ADDED
    

    之后

    data[csrfParameter] = csrfToken;
    data["institutionId"] = option;
    headers[csrfHeader] = csrfToken;    // THIS WAS ADDED
    

    最后改变了ajax调用:

    url: './getMerchantByInstitution.htm',
    headers: headers,    // THIS WAS ADDED
    data: data,//"institutionId=" + option,
    dataType:'json',
    

    让我知道这个是否奏效 .

  • 8

    要在启用CSRF的情况下发出AJAX / JSON请求,您必须将CSRF令牌作为HTTP请求标头传递,而不是参数或其他数据 .

    在页面上,您的元标记应如下所示:

    <meta name="_csrf" content="${_csrf.token}"/>
    <meta name="_csrf_header" content="${_csrf.headerName}"/>
    

    然后,在JS代码中的某处准备值:

    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    

    将CSRF令牌作为标头传递:

    $.ajax({
            type: "GET",
            async: false,
            url: './getMerchantByInstitution.htm',
            data: "institutionId=" + option,
            beforeSend: function(xhr) {
                // here it is
                xhr.setRequestHeader(header, token);
            },
            success: function(obj) {
                //  ....
            },
            ....
    

    虽然它建议使用像JSON.stringify这样的东西来传递数据,但当然这取决于它 .

    参考文献如下:

    http://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html#csrf-include-csrf-token-ajax

    希望这可以帮助 .

  • 19

    这解决了我的问题:

    <meta name="_csrf" th:content="${_csrf.token}"/>
    <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
    

    使用org.thymeleaf.extras:thymeleaf-extras-springsecurity4:3.0.2.RELEASE

相关问题