iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0
Mobile Development

Spring Boot & Android Studio教學系列 第 20

掌握Spring Security:JWT認證過濾器的最佳實踐(EP3)

  • 分享至 

  • xImage
  •  

OncePerRequestFilter

確保一次性處理:

它確保每個HTTP請求只會通過過濾器的doFilterInternal方法處理一次,而不會重複執行。這有助於防止多次處理同一請求,減少不必要的開銷。

適用於自定義邏輯:

您可以擴展OncePerRequestFilter類,實現自定義的處理邏輯,例如處理JWT令牌、執行特定的安全檢查或記錄請求信息。

集成Spring Security:

它通常與Spring Security一起使用,以執行與安全性相關的任務。您可以在自定義的OncePerRequestFilter中訪問Spring Security上下文和安全上下文,以進行身份驗證和授權。

位於過濾器鏈中:

OncePerRequestFilter通常位於Spring Security過濾器鏈的特定位置,可以根據需要添加到鏈中的不同位置,以滿足不同的安全需求。

@Component
@RequiredArgsConstructor
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtService jwtService;
    private final UserDetailsService userDetailsService;
    private final TokenRepository tokenRepository;

    @Override
    protected void doFilterInternal(
        @NonNull HttpServletRequest request,
        @NonNull HttpServletResponse response,
        @NonNull FilterChain filterChain
    ) throws ServletException, IOException {
        final String authHeader = request.getHeader("Authorization");
        final String jwt;
        final String userEmail;
        // 以下條件為沒有攜帶Token的請求
        //如果未攜帶JWT令牌或令牌不以"Bearer "開頭,則直接呼叫filterChain.doFilter,繼續處理下一個過濾器或請求處理程序。
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);
            return;
        }
        jwt = authHeader.substring(7); //取"Bearer "後面的Token
        userEmail = jwtService.extractUsername(jwt); //提取Token中的Email
        //如果用戶名不為null且當前的Security上下文中不存在身份驗證
        if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail); //使用UserDetailsService根據用戶名(Email)加載用戶詳細信息。
            if (jwtService.isTokenValid(jwt, userDetails)) {
                //如果JWT令牌有效,則創建一個UsernamePasswordAuthenticationToken並將其設置到Spring Security的Security上下文中,以確保用戶已成功驗證。
                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                        userDetails,
                        null,
                        userDetails.getAuthorities()
                );
                authToken.setDetails(
                        new WebAuthenticationDetailsSource().buildDetails(request)
                );
                SecurityContextHolder.getContext().setAuthentication(authToken);
            } else {
                return;
            }
        }
        filterChain.doFilter(request, response);
    }
}

OncePerRequestFilter是Spring Security框架提供的一個抽像類,它用於創建自定義的過濾器來處理每個HTTP請求一次,確保每個請求只被處理一次。它通常用於執行與身份驗證、授權、安全性相關的自定義邏輯。

寫到這大致上Security整個流程與配置都寫好了
接下來會去寫一支註冊與登入的API來測試


上一篇
掌握Spring Security:使用JWT實現身份驗證(EP2)
下一篇
掌握Spring Security:登入註冊API測試(EP4)
系列文
Spring Boot & Android Studio教學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言