@@ -8,11 +8,14 @@ import com.nimbusds.jose.proc.SecurityContext
88import org.springframework.beans.factory.annotation.Value
99import org.springframework.context.annotation.Bean
1010import org.springframework.context.annotation.Configuration
11- import org.springframework.security.core.authority.SimpleGrantedAuthority
11+ import org.springframework.core.convert.converter.Converter
12+ import org.springframework.security.authentication.AbstractAuthenticationToken
13+ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
1214import org.springframework.security.oauth2.jose.jws.MacAlgorithm
1315import org.springframework.security.oauth2.jwt.*
14- import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter
16+ import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter
1517import org.yapp.gateway.constants.JwtConstants
18+ import java.util.UUID
1619import javax.crypto.spec.SecretKeySpec
1720
1821@Configuration
@@ -23,6 +26,7 @@ class JwtConfig(
2326 companion object {
2427 private val SIGNATURE_ALGORITHM = MacAlgorithm .HS256
2528 private const val PRINCIPAL_CLAIM = " sub"
29+ private const val NO_AUTHORITY_PREFIX = " "
2630 }
2731
2832 /* *
@@ -65,19 +69,24 @@ class JwtConfig(
6569 }
6670
6771 /* *
68- * 유효성이 검증된 JWT를 Spring Security의 `Authentication` 객체로 변환하는 `JwtAuthenticationConverter`를 등록합니다.
69- * JWT의 'roles' 클레임을 애플리케이션의 권한 정보(`GrantedAuthority`)로 매핑하고, 'sub' 클레임을 사용자의 주체(Principal)로 설정합니다.
72+ * 유효한 JWT를 Spring Security의 `Authentication` 객체로 변환하는 `JwtAuthenticationConverter` 빈을 설정합니다.
7073 *
71- * @return 생성된 `JwtAuthenticationConverter` 객체
74+ * - JWT의 `roles` 클레임을 추출하여 `GrantedAuthority` 리스트로 변환합니다.
75+ * - 기본적으로 붙는 권한 접두어(`SCOPE_`)를 제거하기 위해 빈 문자열로 설정합니다.
76+ * - JWT의 `sub` 클레임(문자열 형태의 UUID)을 `UUID` 타입으로 변환하여 인증 주체(Principal)로 사용합니다.
77+ *
78+ * @return JWT를 `UsernamePasswordAuthenticationToken` 으로 변환하는 Converter
7279 */
7380 @Bean
74- fun jwtAuthenticationConverter (): JwtAuthenticationConverter {
75- val converter = JwtAuthenticationConverter ()
76- converter.setJwtGrantedAuthoritiesConverter { jwt ->
77- val roles = jwt.getClaimAsStringList(JwtConstants .ROLES_CLAIM ) ? : emptyList()
78- roles.map { role -> SimpleGrantedAuthority (role) }
81+ fun jwtAuthenticationConverter (): Converter <Jwt , out AbstractAuthenticationToken > {
82+ val authoritiesConverter = JwtGrantedAuthoritiesConverter ()
83+ authoritiesConverter.setAuthoritiesClaimName(JwtConstants .ROLES_CLAIM )
84+ authoritiesConverter.setAuthorityPrefix(NO_AUTHORITY_PREFIX )
85+
86+ return Converter <Jwt , AbstractAuthenticationToken > { jwt ->
87+ val authorities = authoritiesConverter.convert(jwt)
88+ val principal = UUID .fromString(jwt.getClaimAsString(PRINCIPAL_CLAIM ))
89+ UsernamePasswordAuthenticationToken (principal, null , authorities)
7990 }
80- converter.setPrincipalClaimName(PRINCIPAL_CLAIM )
81- return converter
8291 }
8392}
0 commit comments