WEB/Security

OAuth 2.0 Resource Server API - jwt()

Tony Lim 2022. 12. 22. 17:24
728x90

JWT API 설정 및 검증 프로세스 이해

검증순서

1. client가 Authorization Barer token-value 를 헤더에 담아서 요청한다.
2. 리소스 서버는 요청한 토큰이 Bearer 토큰 사양에 부합하는지 검사한다.
3. 인가서버에서 JWT 토큰에 서명한 개인키와 매칭하는 공개키를 jwt-set-url endpoint 요청으로 가져와서 1번째 검증을 진행한다.
4. jwt에 있는 exp, nbf, iss 클레임의 정보가 기준에 부합하는지 2번째 검증을 진행한다.
5. 검증에 서공하면 jwt 객체를 생성하고 claims 정보에 있는 scope를 추출해서 시큐리티의 권한에 매핑한다. (SCOPE_profile , SCOPE_email)
6. Authentication 객체를 생성하고 Jwt 객체를 principal 속성에 저장한다.
7. Authentication 을 SecurityContext에 저장하고 인증을 완료한다.

JwtDecoder에서 client가 준 token을 검증하기위해서는 auth server의 public key가 필요하다. (현재 jwt는 auth server의 private key로 사인한 상태)


JWTDecoder

 

 


JwtDecoder 생성방법

@Autowired
private OAuth2ResourceServerProperties properties;

@Bean
public JwtDecoder jwtDecoder1(){
    return JwtDecoders.fromIssuerLocation(properties.getJwt().getIssuerUri());
}

@Bean
public JwtDecoder jwtDecoder2(){
    return JwtDecoders.fromOidcIssuerLocation(properties.getJwt().getIssuerUri());
}

@Bean
public JwtDecoder jwtDecoder3(){
    return NimbusJwtDecoder.withJwkSetUri(properties.getJwt().getJwkSetUri())
            .jwsAlgorithm(SignatureAlgorithm.RS512).build();
}

OAuth2ResourceServerProperties를 통해 application.yml에 적힌 값들을 가져오게 된다.

JwtDecoders.fromIssuerLocation() 을 호출하면 Provider 설정 또는 인가서버 metadata endpoint로 jwk-set-uri를 요청한다.
앱에서 따로 정의한 JwtDecoder 빈이 없다면 스프링부트가 등록하는 빈이다. (jwtDecoder1)

final class JwtDecoderProviderConfigurationUtils {
   private static final String OIDC_METADATA_PATH = "/.well-known/openid-configuration";
   private static final String OAUTH_METADATA_PATH = "/.well-known/oauth-authorization-server";

jwtDecoder2는 1과 유사한데 auth server로 부터 meta data를 가져오는 방식만 다른것이다. open id를 지원하지 않는 auth server의 경우에는 jwtDecoder2는 실패할 것이다.

기본적으로 스프링부트에 의해 NimbusJwtDecoder 빈이 자동생성될 경우 리소스 서버는 RS256 을 사용한 토큰만 신뢰하고 이 토큰만 검증할 수 있다.
JwkSetUri에 의한 검증방식으로 NimbusJwtDecoder 를 생성할 경우 알고리즘의 종류를 변경할 수 있으나 RSA 알고리즘(RSA256 default) 에 한해 변경가능하고 HMAC은 지원하지 않음(jwtDecoder3)

 

728x90