捡重要的说
配置说明:项目是基于maven+springMVC+springSecurity的,maven、web.xml和springmvc具体配置可以百度,具体说下springsecurity.xml的配置,
<http pattern="/init" security="none"/>
<http pattern="/login" security="none"/>
<http auto-config="true">
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<form-login
login-page="/login"
default-target-url="/welcome"
authentication-failure-url="/login?error"
username-parameter="uname"
login-processing-url="/j_spring_security_check"
password-parameter="pwd" />
<logout logout-success-url="/login?logout" />
<csrf/>
</http>
如代码所示,我过滤了2条url请求的验证后拦截所有的url请求,springsecurity是4.2.2,由于csrf在4.x之后默认开启,我也就不关闭了,登录页面jsp代码
<form name='loginForm' action="<c:url value='j_spring_security_check' />" method='POST'>
<table>
<form:form>
<tr>
<td>User:</td>
<td><input type='text' name='uname' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='pwd' /></td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit" value="submit" /></td>
</tr>
</form:form>
</table>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
jsp页面代码中有csrf参数,但是当访问 /login的时候,检查页面源码中发现没有csrf参数,这就奇怪了,因为当springsecurity配置改为
<http pattern="/init" security="none"/>
<!--<http pattern="/login" security="none"/>-->
<http auto-config="true">
<intercept-url pattern="/admin" access="hasRole('ROLE_USER')" />
<form-login
login-page="/login"
default-target-url="/welcome"
authentication-failure-url="/login?error"
username-parameter="uname"
login-processing-url="/j_spring_security_check"
password-parameter="pwd" />
<logout logout-success-url="/login?logout" />
<csrf/>
</http>
login页面的就有了csrf令牌了。猜测是配置问题,debug之后发现了第一个配置文件的时候,/login过springspecrutiy过滤器时的过滤器链为0,而第二个配置的过滤器链过滤器为13,在这13个过滤器中,有一个过滤器名字为CsrfFilter,这个就是csrf令牌验证过滤器。在这个过滤器中,会先往request请求中放一个token对象,这个对象包含如下参数:
![debug下的CsrfFilter文件](https://img-blog.csdn.net/20170321104717410?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb3FxTGFpMTIzNDU2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
因此,如果直接过滤掉login请求,则springsecurity无法将token放入jsp页面,该页面无论怎么样也无法获取csrf令牌了。