[#34] 회원 / 인증 도메인 재정의 #43

Merged
pricelees merged 73 commits from refactor/#34 into main 2025-09-13 10:13:45 +00:00
2 changed files with 63 additions and 1 deletions
Showing only changes of commit e02086680b - Show all commits

View File

@ -1,5 +1,7 @@
package roomescape.auth.web.support package roomescape.auth.web.support
import roomescape.admin.infrastructure.persistence.Privilege
@Target(AnnotationTarget.FUNCTION) @Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
annotation class Admin annotation class Admin
@ -10,4 +12,10 @@ annotation class LoginRequired
@Target(AnnotationTarget.VALUE_PARAMETER) @Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
annotation class MemberId annotation class MemberId
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class AdminOnly(
val privilege: Privilege
)

View File

@ -0,0 +1,54 @@
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.admin.infrastructure.persistence.AdminPermissionLevel
import roomescape.auth.business.CLAIM_PERMISSION_KEY
import roomescape.auth.exception.AuthErrorCode
import roomescape.auth.exception.AuthException
import roomescape.auth.infrastructure.jwt.JwtUtils
import roomescape.auth.web.support.AdminOnly
import roomescape.auth.web.support.MDC_MEMBER_ID_KEY
import roomescape.auth.web.support.accessToken
private val log: KLogger = KotlinLogging.logger {}
@Component
class AdminInterceptor(
private val jwtUtils: JwtUtils
) : HandlerInterceptor {
override fun preHandle(
request: HttpServletRequest,
response: HttpServletResponse,
handler: Any
): Boolean {
if (handler !is HandlerMethod) {
return true
}
val annotation: AdminOnly = handler.getMethodAnnotation(AdminOnly::class.java) ?: return true
val token: String? = request.accessToken()
val adminId = jwtUtils.extractSubject(token).also { MDC.put(MDC_MEMBER_ID_KEY, it) }
jwtUtils.extractClaim(
token = token, key = CLAIM_PERMISSION_KEY
).also {
val permission = AdminPermissionLevel.valueOf(it)
if (!permission.hasPrivilege(annotation.privilege)) {
log.warn { "[AuthInterceptor] 관리자 권한 부족: required=${annotation.privilege} / current=${permission}" }
throw AuthException(AuthErrorCode.ACCESS_DENIED)
}
log.info { "[AuthInterceptor] 인증 완료. adminId=$adminId, permission=${permission}" }
}
return true
}
}