π
[μ€νλ§ μνλ¦¬ν° OAuth2] oauth2ResourceServer().opaque()
1. Opaque κ°λ λ° API μ€μ
β κ°λ
- Opaque ν ν°μ μΈκ° μλ²μμ νΈμ€νΈνλ OAuth 2.0 Introspection μλν¬μΈνΈλ‘ κ²μ¦νλ€.
- Bearer ν ν°μ΄ 리μμ€ μλ²μμ μ²λ¦¬νλ μ체 κ²μ¦μ΄λΌλ©΄ Opaque ν ν°μ μΈκ°μλ²μμ μ²λ¦¬νλ μ격 κ²μ¦μ΄λΌκ³ λ³Ό μ μλ€
β νκ²½ μ€μ
-
λ κ°μ§ μ€μ λ§ νλ©΄ μΈκ°μλ²μμ Instrospection κ²μ¦μ΄ κ°λ₯νλ€.
β νμν μμ‘΄μ±μ μΆκ°νλ€
runtimeOnly 'com.nimbusds:oauth2-oidc-sdk:9.35'
β‘ introspection μλν¬μΈνΈ μμΈ μ 보λ₯Ό μ€μ νλ€
spring: security: oauth2: resourceserver: opaquetoken: introspection-uri: http://localhost:8080/realms/oauth2/protocol/openid-connect/introspect client-id: oauth2-client-app client-secret: CQueEWXZYmv7IIZVxbvh2uwxptXVaRcX
- http://localhost:8080/realms/oauth2/protocol/openid-connect/introspect λ μΈκ° μλ²κ° νΈμ€νΈνλ introspection μλν¬μΈνΈμ΄λ€
- client-id μ client-secret μ μλν¬μΈνΈ μμ²μ μ¬μ©ν ν΄λΌμ΄μΈνΈ μ격μ¦λͺ μ΄λ€.
β μ€μ ν΄λμ€
@Configuration(proxyBeanMethods = false)
static class OAuth2ResourceServerConfig {
@Bean
SecurityFilterChain jwtSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaque);
return http.build();
}
}
β OpaqueTokenConfigurer / μ΄κΈ°ν κ³Όμ
2. ν ν° κ²μ¬ λ° νλ‘μΈμ€ μ΄ν΄
β OpaqueTokenIntrospector
- λ¬Έμμ΄ ν ν°μ RestTemplate μ μ¬μ©νμ¬ μΈκ°μλ² μλν¬μΈνΈλ‘ μμ²νλ€
- ν ν°μ΄ κ²μ¦λλ©΄ μ΅μ’ OAuth2AuthenticatedPrincipal νμ μ κ°μ²΄λ‘ λμ½λ©νμ¬ λ°ννλ€.
- OAuth2AuthenticatedPrincipal μ BearerTokenAuthentication μ principal μμ±μ μ μ₯λλ€
β CustomOpaqueTokenIntrospector
- OpaqueTokenIntrospector μΈν°νμ΄μ€λ₯Ό ꡬννμ¬ μ»€μ€ν ν ꡬν체λ₯Ό λ§λ€μ΄ μ¬μ μ ν μ μλ€
- κ²μ¦ ν λ¦¬ν΄ νμ μ΄ OAuth2AuthenticatedPrincipal μ΄κΈ° λλ¬Έμ μΈκ°μλ²μμ λ°μμ¨ ν΄λ μ μ 보λ₯Ό νμ©ν΄μ μ¬λ¬κ°μ§ 컀μ€ν ν μμ μ΄ κ°λ₯νλ€
http
.oauth2ResourceServer(oauth2 -> oauth2
.opaqueToken(opaqueToken -> opaqueToken
.introspector(customOpaqueTokenIntrospector())
)
);
@Bean
public OpaqueTokenIntrospector customOpaqueTokenIntrospector() {
return new CustomOpaqueTokenIntrospector();
}
public class CustomOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
private OpaqueTokenIntrospector delegate =
new NimbusOpaqueTokenIntrospector(" http://localhost:8080/realms/oauth2/protocol/openid-connect/introspect ", "client", "secret");
public OAuth2AuthenticatedPrincipal introspect(String token) {
OAuth2AuthenticatedPrincipal principal = this.delegate.introspect(token); // μΈκ°μλ²λ‘ λΆν° λ°μ ν΄λ μ μ 보λ₯Ό μ μ₯νκ³ μλ€
return new DefaultOAuth2AuthenticatedPrincipal(
principal.getName(), principal.getAttributes(), extractAuthorities(principal)); // 컀μ€ν
νκ² κΆν λ§€ν νλ€
}
private Collection<GrantedAuthority> extractAuthorities(OAuth2AuthenticatedPrincipal principal) {
List<String> scopes = principal.getAttribute(OAuth2IntrospectionClaimNames.SCOPE);
return scopes.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
}
λκΈλ¨κΈ°κΈ°