下面是csrfFilter的过滤过程
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
request.setAttribute(HttpServletResponse.class.getName(), response);
//获取到cookie中的csrf Token(CookieTokenRepository)或者从session中获取(HttpSessionCsrfTokenRepository)
CsrfToken csrfToken = this.tokenRepository.loadToken(request);
final boolean missingToken = csrfToken == null;
//加载不到,则证明请求是首次发起的,应该生成并保存一个新的 CsrfToken 值
if (missingToken) {
csrfToken = this.tokenRepository.generateToken(request);
this.tokenRepository.saveToken(csrfToken, request, response);
}
request.setAttribute(CsrfToken.class.getName(), csrfToken);
request.setAttribute(csrfToken.getParameterName(), csrfToken);
//排除部分不需要验证CSRF攻击的请求方法(默认忽略了GET、HEAD、TRACE和OPTIONS)
if (!this.requireCsrfProtectionMatcher.matches(request)) {
filterChain.doFilter(request, response);
return;
}
//实际的token从header或者parameter中获取
String actualToken = request.getHeader(csrfToken.getHeaderName());
if (actualToken == null) {
actualToken = request.getParameter(csrfToken.getParameterName());
}
if (!csrfToken.getToken().equals(actualToken)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Invalid CSRF token found for "
+ UrlUtils.buildFullRequestUrl(request));
}
if (missingToken) {
this.accessDeniedHandler.handle(request, response,
new MissingCsrfTokenException(actualToken));
}
else {
this.accessDeniedHandler.handle(request, response,
new InvalidCsrfTokenException(csrfToken, actualToken));
}
return;
}
filterChain.doFilter(request, response);
}
用户想要坚持CSRF Token在cookie中。 默认情况下CookieCsrfTokenRepository将编写一个名为 XSRF-TOKEN的cookie和从头部命名 X-XSRF-TOKEN中读取或HTTP参数 _csrf。
//代码如下: .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
我们在日常使用中,可以采用header或者param的方式添加csrf_token,下面示范从cookie中获取token
<form action="/executeLogin" method="post">
<p>Sign in to continue</p>
<div class="lowin-group">
<label>用户名 <a href="#" rel="external nofollow" rel="external nofollow" class="login-back-link">Sign in?</a></label>
<input type="text" name="username" class="lowin-input">
</div>
<div class="lowin-group password-group">
<label>密码 <a href="#" rel="external nofollow" rel="external nofollow" class="forgot-link">Forgot Password?</a></label>
<input type="password" name="password" class="lowin-input">
</div>
<div class="lowin-group">
<label>验证码</label>
<input type="text" name="kaptcha" class="lowin-input">
<img src="/kaptcha.jpg" alt="kaptcha" height="50px" width="150px" style="margin-left: 20px">
</div>
<div class="lowin-group">
<label>记住我</label>
<input name="remember-me" type="checkbox" value="true" />
</div>
<input type="hidden" name="_csrf">
<input class="lowin-btn login-btn" type="submit">
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(function () {
var aCookie = document.cookie.split("; ");
console.log(aCookie);
for (var i=0; i < aCookie.length; i++)
{
var aCrumb = aCookie[i].split("=");
if ("XSRF-TOKEN" == aCrumb[0])
$("input[name='_csrf']").val(aCrumb[1]);
}
});
</script>










