使用spring SecurityContextHolder在tomcat中将会话ID作为null

时间:2015-05-13 11:28:15

标签: java spring session tomcat

我正在尝试使用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的方式之间的区别。

2 个答案:

答案 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;