一.引入
从刚开始学习Spring Security时,在配置类中一直存在这样一行代码:http.csrf().disable();如果没有这行代码导致用户无法被认证。这行代码的含义是:关闭csrf防护。
二.什么是CSRF
CSRF即跨站请求攻击。简单的说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己以前认证过的站点并运行一些操作(如发邮件,发消息,甚至财产操作(如转账和购买商品))。因为浏览器之前认证过,所以被访问的站点会绝点是这是真正的用户操作而去运行.
这就利用了web中用户身份认证验证的一个漏洞:简单的身份验证仅仅能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。
其实可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包含:以你的名义发送邮件;发消息;盗取你的账号;甚至于购买商品、虚拟货币转账…造成的问题包含个人隐私泄露以及财产安全。
三.Spring Security中CSRF
从Spring Security4开始CSRF防护默认开启。默认会拦截请求。进行CSRF处理。CSRF为了保证不是其他第三方网站访问,要求访问时携带参数名为_csrf值为token(token在服务端产生)的内容,如果token和服务端的token匹配成功,则正常访问。
1.实现步骤
1)编写控制器方法
编写控制器方法,跳转到templates中login.html页面。
@GetMapping("/showLogin")
public String showLogin() {
return "login";
}
2)新建login.html
在项目resources下新建templates文件夹,并在文件夹中新建login.html页面。红色部分是必须存在的否则无法正常登录。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action = "/login" method="post">
//在所有表单提交中,都必须添加这个
<input type="hidden" th:value="${_csrf.token}" name="_csrf" th:if="${_csrf}"/>
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
3)修改配置类
在配置类中注释掉CSRF防护失效
//关闭csrf防护
//http.csrf().disable();
四.开启CSRF后的退出登录
如果我们开启了CSRF保护机制,则默认情况下,不能使用get方式的/logout
官方的说明:
翻译一下就是最简单的方式就是使用form表单退出,如果非要使用一个链接退出,可以通过JavaScript模拟一个表单,设置post退出。如果非要使用get方式退出,上图中官方也给出了代码
我们可以这么解决:
<form style="float: right" action="/logout" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<button type='submit'>退出</button>
</form>