Java 使用spring SecurityContextHolder在tomcat中会话id为null

Java 使用spring SecurityContextHolder在tomcat中会话id为null,java,spring,session,tomcat,Java,Spring,Session,Tomcat,我正在尝试使用spring SecurityContextHolder获取会话id。如下 public static String getSessionId(){ String id = null; SecurityContext secContext = SecurityContextHolder.getContext(); Authentication auth = secContext.getAuthentication();

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

您不应使用
auth.getDetails().getSessionId()
来获取当前会话。它不适用于该用途。
WebAuthenticationDetail
的java文档说:

字符串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();

请注意,RequestContextHolder.currentRequestAttributes().getSessionId()在调用时不存在会话时强制创建会话。此外,RequestContextHolder#currentRequestAttributes()可能会产生运行时异常

在我看来,出于日志记录的目的,使用以下代码获取sessionId更好、更安全:

ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpSession session = ra != null ? ra.getRequest().getSession(false) : null;
String sessionId = session != null ? session.getId : null;

这是访问sessionId的正确方式吗?可能不会。您不需要spring安全api,但servlet api:
request.getSession().getId()
关于RequestContextHolder.currentRequestAttributes().getSessionId()的情况如何;要访问会话id?由于我无法访问类中的请求对象,所以我正在尝试获取会话id。我理解了问题所在,那么获取会话id的最佳方法是什么?是RequestContextHolder.currentRequestAttributes().getSessionId();请注意,如果调用时不存在会话,RequestContextHolder.currentRequestAttributes().getSessionId()将强制创建会话。Mover overm currentRequestAttributes可能会产生RuntimeException。在我看来,最好使用以下代码来获取sessionId:ServletRequestAttributes ra=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();HttpSession会话=ra!=无效的ra.getRequest().getSession(false):null;字符串sessionId=会话!=无效的session.getId:null;