1+ package de.tum.cit.aet.auth.config
2+
3+ import de.tum.cit.aet.auth.service.JwtService
4+ import jakarta.servlet.FilterChain
5+ import jakarta.servlet.http.HttpServletRequest
6+ import jakarta.servlet.http.HttpServletResponse
7+ import org.slf4j.LoggerFactory
8+ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
9+ import org.springframework.security.core.context.SecurityContextHolder
10+ import org.springframework.security.core.userdetails.UserDetailsService
11+ import org.springframework.security.web.authentication.WebAuthenticationDetailsSource
12+ import org.springframework.stereotype.Component
13+ import org.springframework.web.filter.OncePerRequestFilter
14+
15+ @Component
16+ class JwtAuthenticationFilter (
17+ private val jwtService : JwtService ,
18+ private val userDetailsService : UserDetailsService
19+ ) : OncePerRequestFilter() {
20+
21+ private val logger = LoggerFactory .getLogger(JwtAuthenticationFilter ::class .java)
22+
23+ override fun doFilterInternal (
24+ request : HttpServletRequest ,
25+ response : HttpServletResponse ,
26+ filterChain : FilterChain
27+ ) {
28+ logger.debug(" JwtAuthenticationFilter: Processing request for URI: ${request.requestURI} " )
29+
30+ // Skip JWT authentication for public endpoints
31+ if (isPublicEndpoint(request.requestURI)) {
32+ logger.debug(" JwtAuthenticationFilter: Skipping JWT authentication for public endpoint: ${request.requestURI} " )
33+ filterChain.doFilter(request, response)
34+ return
35+ }
36+
37+ try {
38+ val token = extractTokenFromRequest(request)
39+ if (token != null && SecurityContextHolder .getContext().authentication == null ) {
40+ val username = jwtService.extractUsername(token)
41+ val userDetails = userDetailsService.loadUserByUsername(username)
42+
43+ if (jwtService.isTokenValid(token, userDetails)) {
44+ val authentication = UsernamePasswordAuthenticationToken (
45+ userDetails, null , userDetails.authorities
46+ )
47+ authentication.details = WebAuthenticationDetailsSource ().buildDetails(request)
48+ SecurityContextHolder .getContext().authentication = authentication
49+
50+ logger.debug(" JwtAuthenticationFilter: Successfully authenticated user: $username " )
51+ }
52+ }
53+ } catch (e: Exception ) {
54+ logger.error(" JWT authentication error: ${e.message} " )
55+ }
56+
57+ filterChain.doFilter(request, response)
58+ }
59+
60+ private fun extractTokenFromRequest (request : HttpServletRequest ): String? {
61+ val authHeader = request.getHeader(" Authorization" )
62+ return if (authHeader != null && authHeader.startsWith(" Bearer " )) {
63+ authHeader.substring(7 )
64+ } else null
65+ }
66+
67+ private fun isPublicEndpoint (uri : String ): Boolean {
68+ val publicEndpoints = listOf (
69+ " /api/auth/register" ,
70+ " /api/auth/login" ,
71+ " /api/auth/refresh" ,
72+ " /actuator"
73+ )
74+ return publicEndpoints.any { uri.startsWith(it) }
75+ }
76+ }
0 commit comments