使用Spring Security通过Ajax无效的CSRF令牌

时间:2017-05-28 20:46:08

标签: java ajax spring-mvc spring-security

我目前正在使用Java和Spring 3.x(通过XML配置)开发Web应用程序。登录页面使用一个嵌入在门户中。此页面应将参数转发给另一个使用Spring Security执行身份验证的JSP。当我禁用CSRF保护时,一切都运行正常,但是当我启用它时,在登录页面上通过Ajax正确完成身份验证,但是当通过提交表单重定向到主页时,请求被拒绝,因为令牌无效。感谢您提出的所有建议,以帮助我解决此问题。

Components Diagram
这就是我的代码在这一刻的表现:

的index.jsp

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page isELIgnored="false"%>
<html>
<head>
<script type="text/javascript" src="<%=request.getContextPath()%>/include/js/home.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/include/js/jquery-1.11.1.min.js"></script>
</head>
<body>
    <form name="frmMain" id="frmMain" action="<%=request.getContextPath()%>/zona-informativa/validacion-acceso/" method="post" autocomplete="off" target="newblank">
        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
        <input type="hidden" name="userDocument" id="userDocument" />
        <input type="hidden" name="userPassword" id="userPassword" />
        <input name="userDocument01" id="userDocument01" maxlength="30" type="text" autocomplete="off" placeholder="Tu doc. Identidad" value="" />
        <br/>
        <input name="userPassword01" id="userPassword01" maxlength="4" type="password" autocomplete="off" placeholder="Contrase&ntilde;a" />
        <br/>
        <button class="orange" type="button" name="button" id="button" onclick="javaScript:validateLogin();">INGRESAR</button>
    </form>
</body>
</html>

float.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page isELIgnored="false"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
<script type="text/javascript" src="<%=request.getContextPath()%>/include/js/jquery-1.11.1.min.js"></script>
<title>Insert title here</title>
</head>
<body>
    <input type="hidden" id="contextPath" value="<%=request.getContextPath()%>" />

    <c:url value="/zona-transaccional/home/?${_csrf.parameterName}=${_csrf.token}" var="urlGoHome"/>
    <form id="frmLogueo" action="${urlGoHome}" method="post" enctype="multipart/form-data">
    </form>
    <script>
        var contextPath = $('#contextPath').val();
        $(document).ready(function() {
            validaLogin();
        });
        function validaLogin() {
            var userDocument = top.window.opener.document.frmMain.userDocument01.value;
            var passwd = top.window.opener.document.frmMain.userPassword01.value;
            //Credentials
            var token = $("meta[name='_csrf']").attr("content");
            var header = $("meta[name='_csrf_header']").attr("content");
            var data = {};
            data['j_username'] = userDocument;
            data['j_password'] = passwd;
            $.ajax({
                type: 'POST',
                url: contextPath + "/zona-informativa/login",
                dataType: 'json',
                data: data,
                beforeSend: function (xhr) {
                    xhr.setRequestHeader(header, token);
                    xhr.setRequestHeader("X-Ajax-call", "true");
                },
                success: function(respuesta) {
                    if(!respuesta.error) {
                        $("#frmLogueo").submit();
                    } else {
                        alert(respuesta.status);
                    }
                },
                error: function(data) {
                    alert("Ocurrio un error interno.");
                }
            });
        }
    </script>
</body>
</html>

弹簧security.xml文件

<b:beans 
    xmlns="http://www.springframework.org/schema/security"
    xmlns:b="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.2.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <b:bean id="provider" class='com.auth.AuthProvider' />
    <b:bean id="success" class="com.auth.AuthSuccess" />
    <b:bean id="failure" class="com.auth.AuthFailure" />

    <http use-expressions="true" authentication-manager-ref="manager">
        <intercept-url pattern="/hello" access="permitAll" />
        <intercept-url pattern="/include/**" access="permitAll" />
        <intercept-url pattern="/zona-informativa/**" access="permitAll" />
        <intercept-url pattern="/zona-transaccional/**" access="hasRole('ROL_AFILIADO')" />

        <form-login 
            login-page="/zona-informativa/validacion-acceso/"
            login-processing-url="/zona-informativa/login"
            authentication-failure-handler-ref="failure"
            authentication-success-handler-ref="success" />
        <logout delete-cookies="JSESSIONID" invalidate-session="true" />
        <csrf/>
    </http>
    <authentication-manager id="manager">
        <authentication-provider ref='provider' />
    </authentication-manager>
</b:beans>

0 个答案:

没有答案