diff --git a/src/main/kotlin/com/android/trisolarisserver/security/FirebaseAuthFilter.kt b/src/main/kotlin/com/android/trisolarisserver/security/FirebaseAuthFilter.kt index 30aaa90..bdaabb3 100644 --- a/src/main/kotlin/com/android/trisolarisserver/security/FirebaseAuthFilter.kt +++ b/src/main/kotlin/com/android/trisolarisserver/security/FirebaseAuthFilter.kt @@ -5,6 +5,7 @@ import com.google.firebase.auth.FirebaseAuth import jakarta.servlet.FilterChain import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse +import org.slf4j.LoggerFactory import org.springframework.http.HttpHeaders import org.springframework.security.authentication.UsernamePasswordAuthenticationToken import org.springframework.security.core.context.SecurityContextHolder @@ -17,6 +18,7 @@ import org.springframework.http.HttpStatus class FirebaseAuthFilter( private val appUserRepo: AppUserRepo ) : OncePerRequestFilter() { + private val logger = LoggerFactory.getLogger(FirebaseAuthFilter::class.java) override fun shouldNotFilter(request: HttpServletRequest): Boolean { val path = request.requestURI @@ -30,6 +32,7 @@ class FirebaseAuthFilter( ) { val header = request.getHeader(HttpHeaders.AUTHORIZATION) if (header.isNullOrBlank() || !header.startsWith("Bearer ")) { + logger.debug("Auth missing/invalid header for {}", request.requestURI) response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing Authorization token") return } @@ -39,6 +42,7 @@ class FirebaseAuthFilter( val firebaseUid = decoded.uid val user = appUserRepo.findByFirebaseUid(firebaseUid) ?: throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "User not found") + logger.debug("Auth verified uid={}, userId={}", firebaseUid, user.id) val principal = MyPrincipal( userId = user.id ?: throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "User id missing"), @@ -48,6 +52,7 @@ class FirebaseAuthFilter( SecurityContextHolder.getContext().authentication = auth filterChain.doFilter(request, response) } catch (ex: Exception) { + logger.debug("Auth failed for {}: {}", request.requestURI, ex.message) response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token") } } diff --git a/src/main/kotlin/com/android/trisolarisserver/security/SecurityConfig.kt b/src/main/kotlin/com/android/trisolarisserver/security/SecurityConfig.kt index eedfb7b..db55415 100644 --- a/src/main/kotlin/com/android/trisolarisserver/security/SecurityConfig.kt +++ b/src/main/kotlin/com/android/trisolarisserver/security/SecurityConfig.kt @@ -2,26 +2,37 @@ package com.android.trisolarisserver.security import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.core.annotation.Order import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.http.SessionCreationPolicy import org.springframework.security.web.SecurityFilterChain import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter @Configuration(proxyBeanMethods = false) -@EnableWebSecurity @EnableMethodSecurity class SecurityConfig( private val firebaseAuthFilter: FirebaseAuthFilter ) { @Bean - fun filterChain(http: HttpSecurity): SecurityFilterChain { + @Order(1) + fun publicChain(http: HttpSecurity): SecurityFilterChain { + http + .securityMatcher("/", "/health", "/auth/**") + .csrf { it.disable() } + .authorizeHttpRequests { it.anyRequest().permitAll() } + .httpBasic { it.disable() } + .formLogin { it.disable() } + return http.build() + } + + @Bean + @Order(2) + fun apiChain(http: HttpSecurity): SecurityFilterChain { http .csrf { it.disable() } .sessionManagement { it.sessionCreationPolicy(SessionCreationPolicy.STATELESS) } .authorizeHttpRequests { - it.requestMatchers("/", "/health", "/auth/**").permitAll() it.anyRequest().authenticated() } .httpBasic { it.disable() }