diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/security/LoggingBasicAuthFilter.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/security/LoggingBasicAuthFilter.kt new file mode 100644 index 000000000..57b9be016 --- /dev/null +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/security/LoggingBasicAuthFilter.kt @@ -0,0 +1,52 @@ +package org.gotson.komga.infrastructure.security + +import mu.KotlinLogging +import org.springframework.security.authentication.AuthenticationManager +import org.springframework.security.authentication.BadCredentialsException +import org.springframework.security.core.Authentication +import org.springframework.security.core.AuthenticationException +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter +import java.security.Principal +import javax.servlet.http.HttpServletRequest +import javax.servlet.http.HttpServletResponse + +private val log = KotlinLogging.logger {} + +class LoggingBasicAuthFilter( + authenticationManager: AuthenticationManager +) : BasicAuthenticationFilter(authenticationManager) { + + override fun onUnsuccessfulAuthentication(request: HttpServletRequest, response: HttpServletResponse, failed: AuthenticationException) { + val cause = when { + failed is BadCredentialsException -> "Bad credentials" + !failed.message.isNullOrBlank() -> failed.message!! + else -> failed.toString() + } + + log.info { "Authentication failure: $cause, ${request.extractInfo()}" } + } + + override fun onSuccessfulAuthentication(request: HttpServletRequest, response: HttpServletResponse, authResult: Authentication) { + val user = when (val p = authResult.principal) { + is KomgaPrincipal -> p.user.email + is Principal -> p.name + else -> p.toString() + } + + log.info { "Authentication success for user: $user, ${request.extractInfo()}" } + } +} + +data class RequestInfo( + val ip: String, + val userAgent: String, + val method: String, + val url: String +) + +fun HttpServletRequest.extractInfo() = RequestInfo( + ip = remoteAddr, + userAgent = getHeader("User-Agent"), + method = method, + url = requestURL.toString() +) diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/security/SecurityConfiguration.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/security/SecurityConfiguration.kt index fc5d48e64..a49c7d1c3 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/security/SecurityConfiguration.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/security/SecurityConfiguration.kt @@ -14,6 +14,7 @@ import org.springframework.security.core.session.SessionRegistry import org.springframework.security.core.session.SessionRegistryImpl import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder import org.springframework.security.crypto.password.PasswordEncoder +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter import org.springframework.web.cors.CorsConfiguration import org.springframework.web.cors.UrlBasedCorsConfigurationSource @@ -23,8 +24,10 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource class SecurityConfiguration( private val komgaProperties: KomgaProperties ) : WebSecurityConfigurerAdapter() { + override fun configure(http: HttpSecurity) { http + .addFilterAt(LoggingBasicAuthFilter(this.authenticationManager()), BasicAuthenticationFilter::class.java) .cors().and() .csrf().disable() .authorizeRequests()