π[μ€νλ§ μνλ¦¬ν° OAuth2] oauth2ResourceServer().jwt()
1. JWT API μ€μ λ° κ²μ¦ νλ‘μΈμ€ μ΄ν΄
β μ€μ ν΄λμ€ μμ±
@Configuration(proxyBeanMethods = false)
public class OAuth2ResourceServerConfig {
@Bean
SecurityFilterChain jwtSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); // jwt ν ν°μ κ²μ¦νλ λΉλ€κ³Ό ν΄λμ€λ₯Ό μμ±νκ³ μ΄κΈ°ν ν¨
return http.build();
}
}
- API μ€μ
- SecurityFilterChain νμ μ λΉμ μμ±ν΄μ 보μ νν°λ₯Ό ꡬμ±νλ€
- HttpSecurity μ μλ oauth2ResourceServer().jwt() API λ₯Ό μ μνκ³ λΉλνλ€
β κ²μ¦ νλ‘μΈμ€ μ΄ν΄
spring.security.oauth2.resourceserver.jwt.issuer-uri = http://localhost:8080/realms/oauth2
- νλ‘νΌν°λ₯Ό μ€μ νλ©΄ JWTλ‘ μΈμ½λ©ν Bearer ν ν°μ κ²μ¦νλ 리μμ€ μλ²κ° μλμΌλ‘ μ€μ λλ€.
- Open ID Connect Provider μ€μ μλν¬μΈνΈ λλ μΈκ° μλ² λ©νλ°μ΄ν° μλν¬μΈνΈλ₯Ό κ²μν΄μ jwk-set-url μλν¬μΈνΈλ₯Ό μ°Ύμ κ²μ¦μ μ§ννλ€
- λκ°μ§ κ²μ¦ μ λ΅μ μ€μ νλ€
- 리μμ€ μλ²λ μΈκ°μλ²μ jwk-set-uri μλν¬μΈνΈλ‘ μ ν¨ν 곡κ°ν€λ₯Ό μ§μνκΈ° μν κ²μ¦ μ λ΅μ μ€μ νλ€
- Issuer-uri(http://localhost:8080/realms/oauth2) μ λν κ° JWT ν΄λ μμ κ²μ¦ν μ λ΅μ μ€μ νλ€
β κ²μ¦ μμ
- ν΄λΌμ΄μΈνΈκ° Authorization Bearer token-value λ₯Ό ν€λμ λ΄μμ μμ²νλ€
- 리μμ€ μλ²λ μμ²ν ν ν°μ΄ Bearer ν ν° μ¬μμ λΆν©νλμ§ κ²μ¬νλ€
- μΈκ°μλ²μμ JWT ν ν°μ μλͺ ν κ°μΈν€μ λ§€μΉνλ 곡κ°ν€λ₯Ό jwk-set-url μλν¬μΈνΈ μμ²μΌλ‘ κ°μ Έμμ 첫λ²μ§Έ κ²μ¦μ μ§ννλ€.
- JWTμ μλ exp, nbf, iss ν΄λ μμ μ λ³΄κ° κΈ°μ€μ λΆν©νλμ§ λλ²μ§Έ κ²μ¦μ μ§ννλ€
- κ²μ¦μ μ±κ³΅νλ©΄ Jwt κ°μ²΄λ₯Ό μμ±νκ³ claims μ 보μ μλ scope λ₯Ό μΆμΆν΄μ μν리ν°μ κΆνμ λ§€ννλ€ (SCOPE_profile, SCOPE_email)
- Authentication κ°μ²΄λ₯Ό μμ±νκ³ Jwt κ°μ²΄λ₯Ό principal μμ±μλ μ μ₯νλ€
- Authentication λ₯Ό SecurityContext μ μ μ₯νκ³ μΈμ¦μ μλ£νλ€
2. JwtDecoder μ΄ν΄
2-1). μκ° λ° μΈλΆ νλ¦
β JwtDecoder μκ°
- JwtDecoder λ λ¬Έμμ΄λ‘ λ JWT(JSON Web Token)λ₯Ό μ»΄ν©νΈ ν΄λ μ νν νμμμ Jwt μΈμ€ν΄μ€λ‘ βλμ½λ©βνλ μν μ νλ€.
- JwtDecoder λ JWT κ° JSON μΉ μλͺ
(JWS) κ΅¬μ‘°λ‘ μμ±λ κ²½μ° JWS μλͺ
μ λν κ²μ¦μ μ±
μμ΄ μλ€.
- κΈ°λ³Έ ꡬνμ²΄λ‘ NimbusJwtDecoder κ° μλ€
β NimbusJwtDecoder
β κ²μ¦ μΈλΆ νλ¦
- JwtDecoder μ decode() λ₯Ό ν΅ν΄ κ²μ¦μ μ±κ³΅νλ©΄ μ΅μ’
μ μΌλ‘ Jwt νμ
μ μΈμ¦κ°μ²΄λ₯Ό λ°ννλ€
2-2). μμ± λ°©λ²
β JwtDecoders.fromIssuerLocation()
@Bean
public JwtDecoder jwtDecoder() {
return JwtDecoders.fromIssuerLocation(properties.getIssuerUri());
}
- JwtDecoders.fromIssuerLocation() μ νΈμΆνλ©΄ Provider μ€μ λλ μΈκ° μλ² λ©νλ°μ΄ν° μλν¬μΈνΈλ‘ JWK μ Uriλ₯Ό μμ²νλ€
- μ΄ν리μΌμ΄μ μμ λ°λ‘ μ μν JwtDecoder λΉμ΄ μλ€λ©΄ μ€νλ§ λΆνΈκ° μμ μλ λν΄νΈ λΉμ λ±λ‘νλ€.
β NimbusJwtDecoder.withJwkSetUri()
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri(properties.getJwkSetUri())
.jwsAlgorithm(SignatureAlgorithm.RS512).build();
}
- κΈ°λ³Έμ μΌλ‘ μ€νλ§ λΆνΈμ μν΄ NimbusJwtDecoder λΉμ΄ μλ μμ±λ κ²½μ° λ¦¬μμ€ μλ²λ RS256 μ μ¬μ©ν ν ν°λ§ μ λ’°νκ³ μ΄ ν ν°λ§ κ²μ¦ν μ μλ€
- JwkSetUri μ μν κ²μ¦λ°©μμΌλ‘ NimbusJwtDecoder λ₯Ό μμ±ν κ²½μ° μκ³ λ¦¬μ¦μ μ’ λ₯λ₯Ό λ³κ²½ν μ μμΌλ RSA μκ³ λ¦¬μ¦μ νν΄ λ³κ²½μ΄ κ°λ₯νκ³ HMAC μ μ§μνμ§ μλλ€
λκΈλ¨κΈ°κΈ°