我正在尝试使用spring SecurityContextHolder获取会话ID。如下所示
public static String getSessionId(){
String id = null;
SecurityContext secContext = SecurityContextHolder.getContext();
Authentication auth = secContext.getAuthentication();
if(auth!=null){
WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails();
if(details!=null){
id = details.getSessionId();
}
}
return id;
}
大部分时间details.getSessionId();
都是空的。有时会返回sessionId。我想知道是什么导致了这一点。它是访问sessionId的正确方法吗?
我试过了RequestContextHolder.currentRequestAttributes().getSessionId();
这会每次都正确返回会话ID。我想知道这两种访问会话ID的方式之间的区别。
答案 0 :(得分:2)
您应不使用auth.getDetails().getSessionId()
来获取当前会话。它不适用于该用途。 WebAuthenticationDetail
的java文档说:
String getSessionId():表示从收到身份验证请求的HttpSession ID。(强调我的)
并为创作者:
public WebAuthenticationDetails(javax.servlet.http.HttpServletRequest request)
Records the remote address and will also set the session Id if a session already exists
(it won't create one).
Parameters:
request - that the authentication request was received from
因此,您获得了收到凭据时存在的会话ID
更糟糕的是,如果您使用的是SessionFixationProtectionStrategy
,则您获得的ID应该是现已失效的会话中的ID,该会话已关闭以防止会话固定攻击。
所以正确的方法是使用RequestContextHolder
:
sessionId = RequestContextHolder.currentRequestAttributes().getSessionId();
答案 1 :(得分:1)
请注意,如果在调用时不存在会话,则 RequestContextHolder.currentRequestAttributes()。getSessionId()会强制创建会话。此外, RequestContextHolder#currentRequestAttributes()可能会产生RuntimeException。
在我看来,出于记录目的,使用以下代码获取sessionId更好,更安全:
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpSession session = ra != null ? ra.getRequest().getSession(false) : null;
String sessionId = session != null ? session.getId : null;