引言
用戶認證通過後,爲了避免用戶的每次操作都進行認證可將用戶的信息保存在會話中。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