RememberMe功能实现
Spring Security中Remember Me为“记住我”功能,用户只需要在登录时添加remember-me复选框,取值为true。Spring Security 会自动把用户信息存储到数据源中,以后就可以不登录进行访问。
<tr>
<td style="width: 30%; text-align: right; padding-right: 5px">
记住我:
</td>
<td style="padding-left: 5px; text-align: left;">
<input type="checkbox" name="remember-me" value="true">
</td>
</tr>
//配置RememberMe
http.rememberMe()
.rememberMeParameter("remember-me") //修改默认参数名,默认是remember-me
.tokenValiditySeconds(60*60*24*14) //设置记住我有效时间,单位是秒,默认是14天
.rememberMeCookieName("remember-me") //修改rememberMe的cookie名称,默认是remember-me
.tokenRepository(persistentTokenRepository) //配置用户登录标记的持久化工具对象
.userDetailsService(userDetailsService); //配置自定义的UserDerailsService接口实现类对象
//关闭CSRF安全协议,关闭是为了完整流程的可用
http.csrf().disable();
}
@Autowired
private PersistentTokenRepository persistentTokenRepository;
@Autowired
private UserDetailsService userDetailsService;
/**
* 创建一个持久化用户登录标记的Respositroy对象
* JdbcTokenRepositoryImpl - 对象,是访问数据库的Repository。
* 需要提供数据库连接 java-connection-mysql
* 所有被@Bean注解描述的方法,其参数,都自动从Spring容器中获取对象,如果没有对象或对象不唯一,抛出异常
* Security持久化用户登录标记,使用的表格,由Security框架创建
* 第一次使用的时候,没有表格,需要让框架创建,后续使用的时候,表格存在,不能让框架创建表格,否则抛出数据库访问异常
* @return
*/
@Bean
public PersistentTokenRepository persistentTokenRepository(DataSource dataSource) {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
//设置启动的时候,在数据库中创建表格persistent_logins。只有数据库中不存在表格的时候可以使用。默认值是false
tokenRepository.setCreateTableOnStartup(true);
return tokenRepository;
}
thymeleaf中使用
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>登录成功</title>
</head>
<body style="width: 800px; text-align: center; margin: auto;">
<h1>欢迎<span style="color:red;" sec:authentication="principal.username"></span>登录 ---------
<a href="/logout" style="color:#076510;">退出登录</a></h1>
<h1>当前用户权限是:<span style="color:red;" sec:authentication="authorities"></span></h1>
<h1 sec:authorize="hasRole('ROLE_管理员')">管理员角色</h1>
<h1 sec:authorize="hasRole('ROLE_访客')">访客角色</h1>
<h1 sec:authorize="hasAuthority('admin:write')">管理员写权限</h1>
<h1 sec:authorize="hasAuthority('admin:read')">管理员读权限</h1>
<h1 sec:authorize="hasAuthority('guest:write')">访客写权限</h1>
<h1 sec:authorize="hasAuthority('guest:read')">访客读权限</h1>
</body>
</html>
CSRF防护
什么是CSRF
CSRF ( Cross-site request forgery )跨站请求伪造,也被称为“One Click Attack",或者Session Riding。通过伪造用户请求访问受信任站点的非法请求访问。
跨域:只要网络协议,ip地址,端口中任何一个不相同就是跨域请求。
客户端与服务进行交互时,由于http协议本身是无状态协议,所以引入了cookie进行记录客户端身份。在cookie 中会存放session id用来识别客户端身份的。在跨域的情况下,session id可能被第三方恶意劫持,通过这个session id向服务端发起请求时,服务端会认为这个请求是合法的,可能发生很多意想不到的事情。
通俗解释︰
CSRF 就是别的网站非法获取我们网站Cookie 值,我们项目服务器是无法区分到底是不是我们的客户端,只有请求中有Cookie,认为是自己的客户端,所以这个时 候就出现了CSRF
<!--SpringSecurity处理登录请求的方式一定是POST-->
<form action="/login" method="post">
<!--需要使用CSRF保护的时候,页面必须经过controller处理,否则没有_CSRF数据-->
<input type="hidden" name="_csrf" th:value="${_csrf.token}">
</form>