Spring Security之默认的过滤器链的CsrfFilter(九)

1.什么是Csrf

CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…造成的问题包括:个人隐私泄露以及财产安全。

通俗的说,就是你用你浏览器缓存的认证信息和用户信息,通过另外一个钓鱼网站去访问你现在浏览器缓存的具有认证信息的网站。然后伪造请求访问那个网站去获取个人信息或者发送危险请求



2.Spring Security的Csrf是如何防御的呢

通过返回一个csrfToken,然后请求发送时需要带上这个token。这个csrfToken可以在头信息中,也可以在参数中。



3.源码解析

@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		request.setAttribute(HttpServletResponse.class.getName(), response);
		// 从token数据源中获取csrfToken
		CsrfToken csrfToken = this.tokenRepository.loadToken(request);
		boolean missingToken = (csrfToken == null);
		if (missingToken) {
			// 如果本地没有token ,生成token
			csrfToken = this.tokenRepository.generateToken(request);
			// 存起来
			this.tokenRepository.saveToken(csrfToken, request, response);
		}
		// 丢到request属性中
		request.setAttribute(CsrfToken.class.getName(), csrfToken);
		request.setAttribute(csrfToken.getParameterName(), csrfToken);
		
		if (!this.requireCsrfProtectionMatcher.matches(request)) {
			// 如果关闭了Csrf防御或者对某些请求不需要Csrf校验,则跳过校验环节
			if (this.logger.isTraceEnabled()) {
				this.logger.trace("Did not protect against CSRF since request did not match "
						+ this.requireCsrfProtectionMatcher);
			}
			filterChain.doFilter(request, response);
			return;
		}
		// 从请求头中获取csrfToken
		String actualToken = request.getHeader(csrfToken.getHeaderName());
		if (actualToken == null) {
			// 当请求头中没有的时候,从参数中获取
			actualToken = request.getParameter(csrfToken.getParameterName());
		}
		// 校验参数
		if (!equalsConstantTime(csrfToken.getToken(), actualToken)) {
			this.logger.debug(
					LogMessage.of(() -> "Invalid CSRF token found for " + UrlUtils.buildFullRequestUrl(request)));
			// 判断到底是非法的CsrfToken异常还是没有CsrfToken异常
			AccessDeniedException exception = (!missingToken) ? new InvalidCsrfTokenException(csrfToken, actualToken)
					: new MissingCsrfTokenException(actualToken);
			// 访问拒绝处理器
			this.accessDeniedHandler.handle(request, response, exception);
			return;
		}
		// 如果验证通过了,那继续往下走
		filterChain.doFilter(request, response);
	}


4.我们看一看AccessDeniedHandler

默认实现是AccessDeniedHandlerImpl ,当然我们可以通过org.springframework.security.web.csrf.CsrfFilter#setAccessDeniedHandler来设置自定义得到AccessDeniedHandler的实现。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rEdxjTKV-1625810901050)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/0ce7cc82-2b86-4d8f-8886-27a2550581f1/Untitled.png)]

上面我们可以看到,如果异常页面存在,则转发至异常页面。否则返回异常码。



5.小结

这样写好像有点慢,有点凑数的感觉。后面简单的就合起来写吧~虽然SpringSecurity给我们添加了很多的安全机制。但是如果不注意,可能就容易认证授权失败。为什么很多人觉得SpringSecurity难用,就是因为你对这个东西没有深入了解过。他是个黑盒,你不遵循他的规则,那你就无法用它。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欢谷悠扬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值