最近的项目中用到spring security4作为权限管理,在整合过程中遇到很多问题,其中关于csrf的的问题纠结了很多次。

1.在配置文件applicationContext-security.xml中如果配置了以下规则

<http pattern="/login.jsp" security="none"/>

那么在login.jsp使用csrf的标签,也就是<security:csrfInput />这个标签会输出为空。也就是无法增加csrf隐藏标签。所以这里一定要注意配置文件,另外防止出现登录死循环这个问题。另外,在使用<security:csrfInput />这个标签时,jsp文件开头一定要引入,如下:

<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>

这个是jsp编程过程中很简单问题。

2.CSRF默认只拦截POST和PUT请求。

3.在WEB-INF/web.xml中,springSecurity过滤器一定要配置在struts2过滤器之前,否则无法过滤action请求。

4.在ExtJs中,Ext.Ajax.request和form.submit({……})这些请求默认采用POST。在开启CSRF情况下需要引入csrf token。解决方式有两种:

在ExtJS所在的JSP页面meta标签中,加入如下标签

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

在同一个页面添加如下代码:

[code lang="js"]

<script type="text/javascript">
var csrftoken = $("meta[name='_csrf']").attr("content");
var csrfheader = $("meta[name='_csrf_header']").attr("content");
var csrfparameter = $("meta[name='_csrf_parameter']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
</script>
[/code]

第一种方式在每个Ext.Ajax.request或者form.submit请求中添加参数项:

params : {'_csrf':csrftoken }

注意'_csrf'这个要与spring security的配置文件中的配置相匹配,默认为_csrf。

第二种方式在每个Ext.Application初始完成之后添加观察者,在每个request之前添加csrfToken。如下,在Ext.application的launch方法中添加

[code lang="js"]

launch: function() {
Ext.mixin.Observable.observe(Ext.data.Connection);//这个方法在ExtJS不同版本中不同,目前我采用的是ExtJS5
});
Ext.data.Connection.on('beforerequest', function(conn, options, eOpts){
conn.setExtraParams({'_csrf' : csrftoken});
});
}
[/code]

spring security4+ExtJs+struts2整合中关于CSRF的问题
Tagged on:         

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据