溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring Security中用JWT退出登錄時遇到的坑有哪些

發(fā)布時間:2021-10-15 17:33:30 來源:億速云 閱讀:292 作者:小新 欄目:開發(fā)技術

這篇文章主要為大家展示了“Spring Security中用JWT退出登錄時遇到的坑有哪些”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Spring Security中用JWT退出登錄時遇到的坑有哪些”這篇文章吧。

Session會話

之所以要說Session會話,是因為Spring Security默認配置就是有會話的,所以當你登錄以后Session就會由服務端保持直到你退出登錄。只要Session保持住,你的請求只要進入服務器就可以從 ServletRequest 中獲取到當前的 HttpSession ,然后會根據 HttpSession 來加載當前的 SecurityContext 。相關的邏輯在Spring Security默認的過濾器 SecurityContextPersistenceFilter 中,有興趣可以看相關的源碼。

而且默認情況下 SecurityContextPersistenceFilter 的優(yōu)先級是高于退出過濾器 LogoutFilter 的,所以能夠保證有Session會話的情況下退出一定能夠獲取當前用戶。

無Session會話

使用了JWT后,每次請求都要攜帶 Bearer Token 并且被專門的過濾器攔截解析之后才能將用戶認證信息保存到 SecurityContext 中去。參考Spring Security實戰(zhàn)干貨教程中的Token認證實現(xiàn) JwtAuthenticationFilter ,相關邏輯為:

// 當token匹配         
if (jwtToken.equals(accessToken)) {
    // 解析 權限集合  這里
    JSONArray jsonArray = jsonObject.getJSONArray("roles");
    List<String> roles = jsonArray.toList(String.class);
    String[] roleArr = roles.toArray(new String[0]);

    List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(roleArr);
    User user = new User(username, "[PROTECTED]", authorities);
    // 構建用戶認證token
    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(user, null, authorities);
    usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
    // 放入安全上下文中
    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
} else {
    // token 不匹配
    if (log.isDebugEnabled()){
        log.debug("token : {}  is  not in matched", jwtToken);
    }
    throw new BadCredentialsException("token is not matched");
}

為什么退出登錄無法獲取當前用戶

分析了兩種情況下用戶認證信息的安全上下文配置后,我們回到問題的本身。來看看為什么用JWT會出現(xiàn)無法獲取當前認證信息的原因。在 HttpSecurity 中,那位同學是這樣配置 JwtAuthenticationFilter 的順序的:

httpSecurity.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
我們再看看 Spring Security 過濾器排序圖:

Spring Security中用JWT退出登錄時遇到的坑有哪些

也就說LogoutFilter執(zhí)行退出的時候,JWT還沒有被 JwtAuthenticationFilter 攔截,當然無法獲取當前認證上下文 SecurityContext 。

解決方法

解決方法就是必須在 LogoutFilter 執(zhí)行前去解析JWT并將成功認證的信息存到 SecurityContext 。我們可以這樣配置:

httpSecurity.addFilterBefore(jwtAuthenticationFilter, LogoutFilter.class)
這樣問題就解決了,你只要實現(xiàn)把當前JWT作廢掉就退出登錄了。

以上是“Spring Security中用JWT退出登錄時遇到的坑有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI