Java 无法使用ajax/json匹配csrf令牌

Java 无法使用ajax/json匹配csrf令牌,java,jsp,struts2,csrf,struts2-interceptors,Java,Jsp,Struts2,Csrf,Struts2 Interceptors,我有一个登录页面,带有一个登录弹出窗口,上面有用户名、密码和验证码。每次尝试使用ajax发布表单(返回值为json)时,都会出现如下错误: com.opensymphony.xwork2.ognl.OgnlValueStack-错误设置表达式'struts.token.name'带值'[Ljava.lang.String;@53401791'ognl.OgnlException:对于getProperty(null,“token”) 及 表单令牌B4KX7L4ER1FXK5BRJZJ19QTGG

我有一个登录页面,带有一个登录弹出窗口,上面有用户名、密码和验证码。每次尝试使用ajax发布表单(返回值为json)时,都会出现如下错误:

com.opensymphony.xwork2.ognl.OgnlValueStack-错误设置表达式
'struts.token.name'
带值
'[Ljava.lang.String;@53401791'
ognl.OgnlException:对于
getProperty(null,“token”)

表单令牌B4KX7L4ER1FXK5BRJZJ19QTGG4EGRGME与会话令牌null不匹配

Login.jsp


var strutsToken=“”;
和内体标签


Signin.jsp(用于登录的弹出窗口)


var strutsToken=“”;
$(文档).ready(函数(){
//用于制作新的验证码图像
var df=“Captcha?token=“+strutsToken+”&struts.token.name=token”;
$(“#IMA”).attr(“src”,df);//IMA是验证码图像的id
$('#mini')。单击(函数(){//mini是提交按钮的id
$.post('Auth'{
用户名:document.getElementById('username')。值,
pass:document.getElementById('pass')。值,
验证码:document.getElementById('Captcha')。值,
token:strutsToken,
'struts.token.name':“token”
},函数(jsonResponse){
如果(jsonResponse.res==“1”){
console.log('valid');
window.location=“活动/campaign\u dashboard.jsp”;
}
如果(jsonResponse.res==“2”){
console.log('valid');
window.location=“Main.jsp”;
}否则{
$('#result').text(jsonResponse.res);
}
}“json”);
});
});
Struts.xml


令牌、dojo\..*、^struts\..*、^session\..*、^request\..*、^application\..*、^servlet(请求|响应)\..*、参数*

是什么阻止令牌正确传递给操作?

您需要将令牌参数从参数拦截器截获的参数中排除

默认情况下,系统会:

通过设置其excludeParams属性,可以强制此拦截器忽略参数。此属性接受以逗号分隔的正则表达式列表。当这些表达式中的任何一个与参数名称匹配时,拦截器将忽略此参数。Struts定义的拦截器堆栈已排除某些参数:

排除的参数的默认列表
dojo\..*、^struts\..*、^session\..*、^request\..*、^application\..*,
^servlet(请求响应)\..*,参数\*
默认情况下,正则表达式的
^struts\..*
部分将排除
struts.token
struts.token.name

您很可能已经覆盖了参数拦截器中默认排除的参数,而没有扩展原始排除的参数

然后:

  • 手动添加令牌参数的排除:

    
    myStuff\..*,struts.token,struts.token.name
    
  • 或者,更好,将自定义排除添加到原始列表中,而不是替换它:

    
    myStuff\..*、dojo\..*、^struts\..*、^session\..*、^request\..*、^application\..*,
    ^servlet(请求响应)\..*,参数\*
    

  • 编辑 添加代码后,我可以看到一些错误:

  • 删除
    myStuff\..*
    ,我把它作为您真正定制的占位符,它是不需要的
  • 将整个正则表达式放在一行中,我将其拆分只是为了提高答案的可读性
  • 您正在参数拦截器上设置参数排除,然后导入本身包含另一个参数拦截器的整个defaultStack。您应该打开defaultStack标记并在那里设置排除(但这并不能解释问题,因为这意味着您没有覆盖默认排除…)
  • 另外,FileUpload拦截器已经在defaultStack中,因此您要运行它两次
  • 然后尝试:

    
    
    如果不起作用,请尝试:

    
    令牌、dojo\..*、^struts\..*、^session\..*、^request\..*、^application\..*、^servlet(请求|响应)\..*、参数*
    
    您需要从参数拦截器截获的令牌参数中排除令牌参数

    默认情况下,系统会:

    通过设置其excludeParams属性,可以强制此拦截器忽略参数。此属性接受以逗号分隔的正则表达式列表。当这些表达式中的任何一个与参数名称匹配时,拦截器将忽略此参数。Struts定义的拦截器堆栈已排除某些参数:

    排除的参数的默认列表
    dojo\..*、^struts\..*、^session\..*、^request\..*、^application\..*,
    ^servlet(请求响应)\..*,参数\*
    
    默认情况下,正则表达式的
    ^struts\..*
    部分将排除
    struts.token
    struts.token.name

    您很可能已经覆盖了参数拦截器中默认排除的参数,而没有扩展原始排除的参数

    然后:

  • 手动添加令牌参数的排除:

    
    myStuff\..*,struts.token,struts.token.name
    
  • 或者,更好,将您的自定义排除添加到原始l