原文: https://javatutorial.net/csrf-protection-in-spring

在本教程中,您将学习如何保护应用程序免受 CSRF 的侵害。

Spring CSRF 保护 - 图1

什么是 CSRF?

如果您已经知道什么 CSRF,请随时继续阅读本分点。 但是,如果您不这样做,CSRF 代表跨站点请求伪造,简单地说,就是攻击者使经过身份验证的用户在网站上执行操作。 结果 – 未经授权的用户执行 Web 应用程序信任的操作

一个典型的例子是,当用户登录时,网站发送分配给 cookie 的令牌信息作为响应的一部分。 现在用户已经登录,攻击者将尝试使用户从 CSRF 攻击开始的地方访问攻击者的网站。 为了使用户访问其网站,攻击者通常通过电子邮件发送电子邮件。 如果用户单击该链接,则网站上有 1 个或什至更多的 API。 与用户访问过的 Cookie 信息一起发送了请求。 现在,攻击者可以对用户的数据/帐户进行未经授权的更改,例如转移资金。

如何预防 CSRF?

有两种方法可以防止 CSRF。

其中之一是通过实现相同的来源策略。 根据此策略,Web 浏览器允许一个网页中包含的脚本访问另一个网页中的数据,但前提是两个网页具有相同的来源。 此方法取决于 HTTP Cookies

另一个是通过应用每个会话/每个请求令牌来过滤作为 CSRF 攻击而来的请求。

Spring 实现中如何防止 CSRF

  1. public class TokenFilter extends OncePerRequestFilter {
  2. @Override
  3. protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
  4. CsrfToken csrfToken = (CsrfToken).request.getAttribute(CsrfToken.class.getName());
  5. if (csrfToken != null) {
  6. Cookie cookie = WebUtils.getCoookie(request, "XSRF-TOKEN");
  7. String token = csrf.getToken();
  8. if (cookie == null || !(token.equals(cookie.getValue())) && token != null) {
  9. cookie = new Cookie("XSRF-TOKEN", token);
  10. cookie.setPath("/");
  11. response.addCookie(cookie);
  12. }
  13. }
  14. filterChain.doFilter(request, response);
  15. }
  16. }

细分

我们创建了一个名为TokenFilter的类来查找特定的 cookie,在这种情况下,它称为XSRF-TOKEN

  1. Cookie cookie = WebUtils.getCoookie(request, "XSRF-TOKEN");

如果没有,则创建一个并分配令牌值,然后将 cookie 添加到服务器响应中。

  1. if (cookie == null || !(token.equals(cookie.getValue())) && token != null) {
  2. cookie = new Cookie("XSRF-TOKEN", token);
  3. cookie.setPath("/");
  4. response.addCookie(cookie);
  5. }

因此,我们设法编写了自己的Filter类来查找特定的 cookie,以防止 CSRF;如果该 cookie 存在,则将其添加到服务器响应中;如果不存在,则使用给定名称创建一个新的 cookie。