本文介绍了 Spring Security 的一些常用功能,包含 Remember Me 功能的设置,如何在 Thymeleaf 中使用 Spring Security 登录信息,如何退出登录,csrf 功能的简单介绍。
Remember Me 功能
默认情况下,用户的登录信息存储在 Session 域,关闭浏览器,就需要重新登录。
Spring Security 支持"Remember Me"(记住我)功能,用户在登陆时添加 remember-me 复选框,取值为 true,Spring Security 就可以自动将用户信息储存到数据源中,一段时间内可以不登陆进行访问。
-
配置 RememberMeConfig(主要是为了使用 dataSource 创建 Repository)
@Configuration public class RememberMeConfig { @Autowired private DataSource dataSource; @Bean PersistentTokenRepository persistentTokenRepository() { JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl(); // 创建表,我们可以在第一次启动时加入这行 // jdbcTokenRepository.setCreateTableOnStartup(true); jdbcTokenRepository.setDataSource(dataSource); return jdbcTokenRepository; } }
-
配置 WebSecurityConfig,将需要记住的 UserDetailsService 和存储目标的 TokenRepository 进行配置。
http.rememberMe() // 设置 token 的有效时间为 7 天,默认是 120s .tokenValiditySeconds(60 * 60 * 24 * 7) .userDetailsService(userDetailsService) .tokenRepository(persistentTokenRepository);
-
前端页面需要响应地进行修改,增加 remember-me 属性:
<form action="/login" method="post"> 用户名:<input type="text" name="myUsername"/> <br> 密码:<input type="password" name="myPassword"/> <br> 记住我:<input type="checkbox" name="remember-me" value="true"> <br> <input type="submit"> </form>
-
登录一次后,会创建 persistent_logins 表,存储登陆用户的信息。
此时,关闭浏览器重新启动,仍然可以直接访问(自己权限足够的)页面。
在 Thymeleaf 中使用登录信息
-
导入依赖
<dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> <version>3.1.1.RELEASE</version> </dependency>
-
在 html 中可以通过
sec: authentication="XXX"
的形式获取各种信息:也可以使用各种函数进行 if 的权限判断,返回为真,标签生效:
退出登录
默认,Spring Security 的退出登录绑定在 /logout,访问 http://localhost:8080/logout 即可实现退出登录。
默认情况下,访问 /logout 会退出登录,然后跳转到 /login?logout 页面。如果想修改这个页面,可以在 WebSecurityConfig 配置:
// 退出登录相关配置
http.logout()
.logoutSuccessUrl("/showLogin");
此外,http.logout() 还可以配置退出登录的地址、使用重定向、配置 Handler 等等。
关于 csrf
csrf 的全称是 Cross-Site Request Forgery「跨站请求伪造」,也被称为 One Click Attack 或 Session Riding,通过伪造用户请求访问受信任站点的非法请求访问。
客户端与服务器进行交互时,由于 HTTP 的无状态特性,引入了 Cookie 来记录客户端身份,在 Cookie 中会存放 Session id 用来识别客户端的身份,在跨域情况下,Session id 可能被第三方恶意劫持,通过这个 session id 向服务器发送请求,服务端就会认为其合法,从而造成风险。
我们前面为了方便,关闭了 csrf 功能:
http.csrf().disable();
将它注释掉,就开启 csrf 功能,此时,在登录页面,需要加上 _csrf
的相关配置:
<form action="/login" method="post">
<input type="hidden" th:value="${_csrf.token}" name="_csrf" th:if="${_csrf}">
用户名:<input type="text" name="myUsername"/> <br>
密码:<input type="password" name="myPassword"/> <br>
记住我:<input type="checkbox" name="remember-me"> <br>
<input type="submit">
</form>
这样,在外域就无法直接访问 /login 页面进行登录了(必须通过 showLogin 页面访问 /login)。
小结
- Remember Me 功能是通过在 WebSecurityConfig 类中进行配置
http.rememberMe()
实现的,需要配置 userDetailsService 和 tokenRepository。 - 在 Thymeleaf 中使用登录信息需要导入 thymeleaf-extras-springsecurity5 依赖,然后就可以使用 sec:authorize 属性查看信息内容或使用权限表达式。
- Spring Security 的退出登录默认绑定在 /logout,可以通过
http.logout()
进行配置。 - csrf 是跨站请求伪造,开启 csrf 时,需要在前端发送页面加入参数
_csrf
。