|
3 | 3 | import demo.codeexample.user.domain.UserRepository; |
4 | 4 | import jakarta.servlet.FilterChain; |
5 | 5 | import jakarta.servlet.ServletException; |
| 6 | +import jakarta.servlet.http.Cookie; |
6 | 7 | import jakarta.servlet.http.HttpServletRequest; |
7 | 8 | import jakarta.servlet.http.HttpServletResponse; |
8 | 9 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
@@ -32,40 +33,64 @@ protected void doFilterInternal(HttpServletRequest request, |
32 | 33 | FilterChain filterChain) |
33 | 34 | throws ServletException, IOException { |
34 | 35 |
|
| 36 | + // 1. Try Authorization header first (API calls from Insomnia/frontend) |
| 37 | + String token = extractFromHeader(request); |
35 | 38 |
|
36 | | - // 1. Look for the Authorization header |
37 | | - String authHeader = request.getHeader("Authorization"); |
| 39 | + // 2. If no header, try cookie (web browser after OAuth2/form login) |
| 40 | + if (token == null) { |
| 41 | + token = extractFromCookie(request); |
| 42 | + } |
38 | 43 |
|
39 | | - if (authHeader == null || !authHeader.startsWith("Bearer ")) { |
| 44 | + // 3. If no token found anywhere — pass through unauthenticated |
| 45 | + if (token == null) { |
40 | 46 | filterChain.doFilter(request, response); |
41 | 47 | return; |
42 | 48 | } |
43 | 49 |
|
44 | | - // 2. Extract the token (remove "Bearer " prefix) |
45 | | - String token = authHeader.substring(7); |
46 | | - |
47 | | - // 3. Validate the token |
| 50 | + // 4. Validate token |
48 | 51 | if (!jwtService.isTokenValid(token)) { |
49 | 52 | filterChain.doFilter(request, response); |
50 | 53 | return; |
51 | 54 | } |
52 | 55 |
|
53 | | - // 4. Extract email and load user |
54 | | - String role = jwtService.extractRole(token); |
55 | | - Long userId = jwtService.extractUserId(token); |
| 56 | + // 5. Extract claims |
| 57 | + String role = jwtService.extractRole(token); |
| 58 | + Long userId = jwtService.extractUserId(token); |
56 | 59 |
|
57 | | - // 5. Tell Spring Security "this user is authenticated" |
| 60 | + // 6. Set authentication in Spring Security context |
58 | 61 | UsernamePasswordAuthenticationToken authentication = |
59 | 62 | new UsernamePasswordAuthenticationToken( |
60 | 63 | userId, |
61 | 64 | null, |
62 | 65 | List.of(new SimpleGrantedAuthority("ROLE_" + role)) |
63 | 66 | ); |
64 | 67 |
|
65 | | - SecurityContextHolder.getContext().setAuthentication(authentication); // SecurityContext = Spring's memory of "who is currently logged in" |
66 | | - |
67 | | - // 6. Continue to the actual endpoint |
| 68 | + SecurityContextHolder.getContext().setAuthentication(authentication); |
68 | 69 | filterChain.doFilter(request, response); |
| 70 | + } |
| 71 | + |
| 72 | + // ───────────────────────────────────────── |
| 73 | + // PRIVATE HELPERS |
| 74 | + // ───────────────────────────────────────── |
| 75 | + |
| 76 | + private String extractFromHeader(HttpServletRequest request) { |
| 77 | + String authHeader = request.getHeader("Authorization"); |
| 78 | + if (authHeader != null && authHeader.startsWith("Bearer ")) { |
| 79 | + return authHeader.substring(7); |
| 80 | + } |
| 81 | + return null; |
| 82 | + } |
| 83 | + |
| 84 | + private String extractFromCookie(HttpServletRequest request) { |
| 85 | + if (request.getCookies() == null) return null; |
69 | 86 |
|
| 87 | + for (Cookie cookie : request.getCookies()) { |
| 88 | + if ("jwt".equals(cookie.getName())) { |
| 89 | + return cookie.getValue(); |
| 90 | + } |
| 91 | + } |
| 92 | + return null; |
70 | 93 | } |
| 94 | + |
| 95 | + |
71 | 96 | } |
0 commit comments