引言
用户认证通过后,为了避免用户的每次操作都进行认证可将用户的信息保存在会话中。spring security提供会话管理,认证通过后将身份信息放入SecurityContextHolder上下文,SecurityContext与当前线程进行绑定,方便获取用户身份。
如何获取用户身份
编写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;
}
/**
* 测试资源1
* @return
*/
@GetMapping(value = "/r/r1",produces = {"text/plain;charset=UTF-8"})
public String r1(){
String username = getUsername();
return username + " 访问资源1";
}
/**
* 测试资源2
* @return
*/
@GetMapping(value = "/r/r2",produces = {"text/plain;charset=UTF-8"})
public String r2(){
String username = getUsername();
return username + " 访问资源2";
}
}
会话控制方法
我们可以通过以下选项准确控制会话何时创建以及Spring Security如何与之交互:
通过以下配置方式对该选项进行配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
}
默认情况下,Spring Security会为每个登录成功的用户会新建一个Session,就是ifRequired 。
若选用never,则指示Spring Security对登录成功的用户不创建Session了,但若你的应用程序在某地方新建了session,那么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_SESSION")
.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