diff --git a/src/main/kotlin/roomescape/auth/web/support/AuthAnnotations.kt b/src/main/kotlin/roomescape/auth/web/support/AuthAnnotations.kt index 55490e4b..f06e0bc2 100644 --- a/src/main/kotlin/roomescape/auth/web/support/AuthAnnotations.kt +++ b/src/main/kotlin/roomescape/auth/web/support/AuthAnnotations.kt @@ -23,3 +23,11 @@ annotation class AdminOnly( @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) annotation class UserOnly + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +annotation class Authenticated + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +annotation class Public diff --git a/src/main/kotlin/roomescape/auth/web/support/interceptors/AuthenticatedInterceptor.kt b/src/main/kotlin/roomescape/auth/web/support/interceptors/AuthenticatedInterceptor.kt new file mode 100644 index 00000000..ff248ff1 --- /dev/null +++ b/src/main/kotlin/roomescape/auth/web/support/interceptors/AuthenticatedInterceptor.kt @@ -0,0 +1,50 @@ +package roomescape.auth.web.support.interceptors + +import io.github.oshai.kotlinlogging.KLogger +import io.github.oshai.kotlinlogging.KotlinLogging +import jakarta.servlet.http.HttpServletRequest +import jakarta.servlet.http.HttpServletResponse +import org.slf4j.MDC +import org.springframework.stereotype.Component +import org.springframework.web.method.HandlerMethod +import org.springframework.web.servlet.HandlerInterceptor +import roomescape.auth.business.AuthServiceV2 +import roomescape.auth.business.CLAIM_TYPE_KEY +import roomescape.auth.infrastructure.jwt.JwtUtils +import roomescape.auth.web.support.Authenticated +import roomescape.auth.web.support.MDC_MEMBER_ID_KEY +import roomescape.auth.web.support.accessToken +import roomescape.common.dto.PrincipalType + +private val log: KLogger = KotlinLogging.logger {} + +@Component +class AuthenticatedInterceptor( + private val jwtUtils: JwtUtils, + private val authService: AuthServiceV2 +) : HandlerInterceptor { + + override fun preHandle( + request: HttpServletRequest, + response: HttpServletResponse, + handler: Any + ): Boolean { + if ((handler !is HandlerMethod) || (handler.getMethodAnnotation(Authenticated::class.java) == null)) { + return true + } + + val token: String? = request.accessToken() + + val id = jwtUtils.extractSubject(token).also { MDC.put(MDC_MEMBER_ID_KEY, it) } + val type = jwtUtils.extractClaim(token, CLAIM_TYPE_KEY) + + try { + authService.findContextById(id.toLong(), PrincipalType.valueOf(type)) + log.info { "[AuthenticatedInterceptor] 인증 완료. id=$id, type=${type}" } + + return true + } catch (e: Exception) { + throw e + } + } +}