🔥 TIL-Day 75 KotlinとSpringboot 06トークンによる認証実装2(認証+同じURIに対する処理-エージェントモード)
以前Spring Securityが実装されていなかった認証には、権限の検証は含まれていません.
今回は,認証権限などのURIであっても,
📌 権限検証の追加
Jwtタグを生成する場合、Climで権限を持ちます.
次に、JWTUtilsクラスに、JWTに対する権限検証を実行する方法を追加します.
売り手権限の検証(ROLE SELLER)が必要な場合は、以下のパラメータで設定できます.
既存の場合、URIを要求するだけで認証を行うインタフェースが適用されるか否かを判断する.
しかしながら、Rest APIについては、通常、同じURI上で異なるHTTPメソッドが用いられる.
ex)
GET/articles=>投稿の表示(検証不要)
POST/articles=>投稿の登録(認証が必要)
Intercepterでは
(if... if ... if ... if..........)
このような重複作業を減らすために,認証インタフェースを適用するか否かを判断する論理を排除する.による実際の検証のためのインタフェース. で実際に検証を行うURI、HTTPメソッドの設定方法を定義します.( クライアント要求URIおよびHTTPメソッドが これは,実際の認証を実行するIntercepterの前にエージェント感覚を追加して要求に適合させるIntercepterである.
📌 IntercepterとArcgumentResolverの登録
今回は,認証権限などのURIであっても,
Http Method
によって認証が必要か否かを区切る機能を実現する.📌 権限検証の追加
Jwtタグを生成する場合、Climで権限を持ちます.
次に、JWTUtilsクラスに、JWTに対する権限検証を実行する方法を追加します.
fun verifySellerToken(token: String): Boolean {
try {
val claims = getAllClaims(token)
val expiration = claims.expiration // 만료기간 검증
if (!expiration.after(Date())) return false
when(val role = claims["role"]) {
is String -> {
return role.equals("ROLE_SELLER") // 권한검증
}
else -> throw IllegalArgumentException("타입에러")
}
} catch (e: JwtException) {
return false
} catch (e: IllegalArgumentException) {
return false
}
}
📌 アクセス権を検証するためのインタフェースの定義売り手権限の検証(ROLE SELLER)が必要な場合は、以下のパラメータで設定できます.
@Component
class RoleVerifyInterceptor(private val jwtTokenProvider: JwtTokenProvider): HandlerInterceptor {
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
if(isPreRequest(request)) return true
val token = JwtTokenExtractor.extract(request)
token?.let {
if(jwtTokenProvider.verifySellerToken(it)) return true
}
throw AuthenticationException("인증실패")
}
private fun isPreRequest(request: HttpServletRequest): Boolean {
return request.method.equals(HttpMethod.OPTIONS)
}
}
📌 Httpメソッドに従ってインタフェースを適用するかどうかを決定する既存の場合、URIを要求するだけで認証を行うインタフェースが適用されるか否かを判断する.
しかしながら、Rest APIについては、通常、同じURI上で異なるHTTPメソッドが用いられる.
ex)
GET/articles=>投稿の表示(検証不要)
POST/articles=>投稿の登録(認証が必要)
Intercepterでは
HttpServletRequest
を使用することができるので、要求URIおよびHTTPメソッドを識別することができる.しかし、各リクエストメソッドに対してブランチ操作を実行することは、非常に煩雑で重複するタスクである.(if... if ... if ... if..........)
このような重複作業を減らすために,認証インタフェースを適用するか否かを判断する論理を排除する.
class PatternMatcherInterceptor(
var targetInterceptor: HandlerInterceptor, // 적용될 인터셉터
) : HandlerInterceptor {
var addPathPatterns: MutableMap<String, HttpMethod> = mutableMapOf() // 인터셉터를 적용조건 <요청URI, 요청메서드>
fun addPathPatterns(uri: String, httpMethod: HttpMethod) = this.addPathPatterns.put(uri, httpMethod)
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
val method = request.method
val requestURI = request.requestURI
// URI와 요청메서드가 일치하는 경우 targetInterceptor 를 통하도록 처리
for (uri in addPathPatterns.keys) {
if (requestURI.equals(uri) && addPathPatterns[uri].toString() == method) {
return targetInterceptor.preHandle(request,response, handler)
}
}
return true
}
}
生成者入力addPathPatterns
) addPathPatterns
に存在する場合、実際の検証を実行するインタフェースが呼び出される.( targetInterceptor.preHandle
) 📌 IntercepterとArcgumentResolverの登録
@Configuration
class WebMvcConfig(
private val tokenVerifyInterceptor: TokenVerifyInterceptor,
private val roleVerifyInterceptor: RoleVerifyInterceptor,
private val authenticatedUserArgumentResolver: AuthenticatedUserArgumentResolver) : WebMvcConfigurer{
override fun addInterceptors(registry: InterceptorRegistry) {
val patternMatcherInterceptor1 = PatternMatcherInterceptor(roleVerifyInterceptor) // 판매자 권한 검증을 위한 인터셉터
patternMatcherInterceptor1.addPathPatterns("/test/auth-test/seller", HttpMethod.GET)
val patternMatcherInterceptor2 = PatternMatcherInterceptor(tokenVerifyInterceptor) // 일반 검증 인터셉터
patternMatcherInterceptor2.addPathPatterns("/items", HttpMethod.POST)
patternMatcherInterceptor2.addPathPatterns("/test/auth-test", HttpMethod.GET)
registry.addInterceptor(patternMatcherInterceptor1)
.addPathPatterns("/**")
registry.addInterceptor(patternMatcherInterceptor2)
.addPathPatterns("/**")
}
override fun addArgumentResolvers(resolvers: MutableList<HandlerMethodArgumentResolver>) {
resolvers.add(authenticatedUserArgumentResolver)
}
}
Reference
この問題について(🔥 TIL-Day 75 KotlinとSpringboot 06トークンによる認証実装2(認証+同じURIに対する処理-エージェントモード)), 我々は、より多くの情報をここで見つけました https://velog.io/@dhk22/TIL-Day-75-Kotlin-Springboot-06-SpringSecurity-없이-토큰기반-인증-구현-2-권한검증-같은-URI에-대한-처리-Proxy-패턴テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol