用户认证通过后,为了避免用户的每次操作都进行认证可将用户的信息保存在会话中。spring
security提供会话管理,认证通过后将身份信息放入SecurityContextHolder上下文,SecurityContext与当前线程进行绑定,方便获取用户身份。
4.4.1 获取用户身份
编写LoginController,实现/r/r1、 /r/r2的测试资源,并修改loginSuccess方法,注意getUsername方法,Spring Security 获取当前登录用户信息的方法为 SecurityContextHolder.getContext().getAuthentication()
@RestController
public class Logincontroller {
/**
*用户登录成功
* @return
*/
@RequestMapping( value = "/login-success", produces = {
"text/plain; charset=UTF-8"})
public String loginSuccess(){
String username = getUsername();
return username + "登录成功";
}
/**
*获取当前登录用户名
* @return
*/
private String getUsername(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(!authentication.isAuthenticated()){
return null;
}
Object principal = authentication.getPrincipal();
String username = null;
if (principal instanceof org.springframework.security.core.userdetails.UserDetails) {
username =((org.springframework.security.core.userdetails.UserDetails)principal).getUsername();
} else {
username = principal.toString();
}
return username;
}
测试
登录前访问资源 被重定向至登录页面。
登录后访问资源 成功访问资源,如下:
zhang san访冋资源1
4.4.2 会话控制
我们可以通过以下选项准确控制会话何时创建以及Spring Security如何与之交互:
机制 | 描述 |
---|---|
always | 如果没有session存在就创建一个 |
ifRequired | 如果需要就仓U建一个Session (默认)登录时 |
never | SpringSecurity将不会创建Session ,但是如果应用中其他地方创建了Session ,那么Spring Security将会使用它。 |
stateless | SpringSecurity将绝对不会创建Session ,也不使用Session |
通过以下配置方式对该选项进行配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
}
默认情况下,Spring Security会为每个登录成功的用户会新建一个Session ,就是ifRequired。
若选用never,则指示Spring Security对登录成功的用户不创建Session了,但若你的应用程序在某地方新建了 session ,月B么Spring Security会用它的。
若使用stateless,则说明Spring Security对登录成功的用户不会创建Session ,你的应用程序也不会允许新建 session。并且它会暗示不使用cookie ,所以每个请求都需要重新进行身份验证。这种无状态架构适用于REST API及袞状态认证机制。
会话超时
可以在sevlet容器中设置Session的超时时间,如下设置Session有效期为3600s ; spring boot配置文件:
server.servlet.session.timeout=3600s
session超时之后,可以通过Spring Security设置跳转的路径。
http.sessionManagement()
.expiredUrl( "/login-view?error=EXPIRED_SESSI0Nn")
.invalidSessionUrl("/login-view?error=INVALID_SESSION");
expired指session过期,invalidSession指传入的sessionid无效。
安全会话cookie
我们可以使用httpOnly和secure标签来保护我们的会话cookie :
- httpOnly :如果为true ,那么浏览器脚本将无法访问cookie
- secure :如果为true,则cookie将仅通过HTTPS连接发送
spring boot配置文件:
server.servlet.session.cookie.http-only=true server.servlet.session.cookie.secure=true