CSRF概述

CSRF(Cross-site request forgery):跨站请求伪造,也被称为 one-click attack 或者 session ridding,通常缩写为 CSRF 或 XSRF。是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。和XSS(跨站脚本攻击)相比,XSS利用的是用户对指定网站的信任,CSRF利用的是网站对用户网页浏览器的信任。

攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件、发消息、甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了Web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发起的。

从Spring Security 4.0开始,默认情况下会启用CSRF防护,以防止CSRF攻击应用程序,Spring Security CSRF 会针对 PATCH、POST、PUT和DELETE方法进行防护。

配置

  1. 注释掉自定义WebSecurityConfigurerAdapterconfigure(HttpSecurity http)方法里面的CSRF配置:

    1. @Override
    2. protected void configure(HttpSecurity http) throws Exception {
    3. //.........
    4. // http.csrf().disable(); // Spring Security默认开启了CSRF防护,disable可以关闭CSRF防护
    5. //.........
    6. }
  1. 在登录页面添加一个thymeleaf的隐藏输入框
    1. <!-- pom中引入thymeleaf依赖 -->
    2. <dependency>
    3. <groupId>org.thymeleaf.extras</groupId>
    4. <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    5. </dependency>
<!DOCTYPE html>
<!-- 引入Thymeleaf的声明 -->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
    <form action="/user/login" method="post">

        <!-- 加入防止CSRF攻击的隐藏输入框 -->
        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">

        用户名:<input type="text" name="username">
        <br>
        密码:<input type="password" name="password">
        <br>
        <input type="submit" value="login">
    </form>
</body>
</html>

Spring Security预防CSRF的原理

  1. 生成 csrfToken 保存到 HttpSession 或者 Cookie中
  2. 客户端请求后台时会带着token字符串访问,服务端比较客户端发来的token和session中存储的token是否一致