iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0
Mobile Development

Android與Spring Boot開發學習之旅系列 第 15

開發學習之旅 Day15 - 使用 JSON Web Token 進行身份驗證(二)

  • 分享至 

  • xImage
  •  

OncePerRequestFilter是一個過濾器基類,確保過濾器邏輯只會在每個HTTP請求中執行一次,有助於確保正確行為並減少重複執行的風險。

繼承OncePerRequestFilter並實現doFilterInternal方法,在這個方法中編寫過濾器的具體邏輯,例如驗證或授權檢查。

這是一個簡單的範例,使用OncePerRequestFilter:

建立 JwtAuthenticationFilter 繼承 OncePerRequestFilter

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

    private final JwtService jwtService;
    private final UserDetailsService userDetailsService;

    @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;

        // 檢查是否有有效的 JWT 令牌
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);
            return;
        }

        jwt = authHeader.substring(7); // 提取JWT令牌
        userEmail = jwtService.extractUsername(jwt); // 提取JWT中的使用者電子郵件

        // 檢查當前的 Spring Security 上下文中是否存在身份驗證
        if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);
            if (jwtService.validateToken(jwt, userDetails)) {
                // 如果JWT令牌有效,設置身份驗證信息到Spring 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);
    }
}
  • doFilterInternal 方法是執行過濾操作的地方
    • 檢查請求的Authorization標頭,確保其中是否包含JWT令牌,通常以Bearer開頭。
    • 如果沒有包含有效的JWT令牌,則呼叫filterChain.doFilter繼續處理下一個過濾器或請求處理程序。
    • 如果當前的Spring Security上下文中不存在身份驗證,執行以下操作
      • userDetailsService 獲取使用者的信息。
      • 如果 JWT 令牌有效,則創建一個 UsernamePasswordAuthenticationToken 並將其設置到 Spring Security 的上下文中。
    • 最後,呼叫filterChain.doFilter,繼續處理請求。

OncePerRequestFilter確保每個請求中的JWT令牌有效且未遭篡改,並將身份信息設置到Spring Security上下文中,實現身份認證和授權,確保只有合法的使用者能夠訪問特定的端點或資源。


上一篇
開發學習之旅 Day14 - 使用 JSON Web Token 進行身份驗證(一)
下一篇
開發學習之旅 Day16 - 使用 JSON Web Token 進行身份驗證(三)
系列文
Android與Spring Boot開發學習之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言