SpringSecurity6.0版本 CSRF验证的处理

问题描述

6版本(starter 3版本)之前,我们可以简单地通过如下代码开启CSRF验证,并且将token通过Cookie提供给前端

http.csrf()
	.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
;

默认设置下前端可以从XSRF-TOKEN字段拿到token,然后把它丢到请求header中的X-XSRF-TOKEN字段中即可

6版本之后会发现单纯这样开启时按照以往的请求方式会被拦截并302到登陆界面,此时,cookie里有XSRF-TOKEN字段,而302的网页里也有一段

<input name="_csrf" type="hidden" value="xsAQ1pzqT6wQB6SZxE8QXANbvNNXV483n1xCBpbhmQKqRRO_p_J04avffM89Y5SgoWIkPTE4kbFgZLoa_G91ZKXQrDuddCeH" />

而网页里的这个才是真正的 token ,cookie里的那个是无效的。

解决方案

将上述开启代码改为

http.csrf()
	.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
    .csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())
;

问题追踪

CSRF验证由CsrfFilter类负责,查看该类的doFilterInternal方法,以debug模式运行发现这里的actualToken null导致匹配不成功

String actualToken = this.requestHandler.resolveCsrfTokenValue(request, csrfToken);

其中requestHandler的定义为

private CsrfTokenRequestHandler requestHandler = new XorCsrfTokenRequestAttributeHandler();

查看该方法的实现

@Override
	public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken) {
		String actualToken = super.resolveCsrfTokenValue(request, csrfToken);
		return getTokenValue(actualToken, csrfToken.getToken());
	}

debug模式运行发现这里的在执行了父类的方法后actualToken 是有值的,那么罪魁祸首就是getTokenValue这个方法,这是一个静态方法,老实说它写了啥我看不懂

但是我们发现XorCsrfTokenRequestAttributeHandler这个类有一个父类CsrfTokenRequestAttributeHandler,它没有重写resolveCsrfTokenValue方法,而且有无参构造方法,那么直接new一个覆盖原定义就好了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值