Spring Security ‐ OAuth 2.0 Resource Server API - dnwls16071/Backend_Summary GitHub Wiki

📚 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();
    }
}
  • SecurityFilterChain 타입의 빈을 생성해서 보안 필터를 구성한다.
  • HttpSecurity에 있는 oauth2ResourceServer().jwt() API를 정의하고 빌드한다.
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://localhost:8080/realms/oauth2
  • 프로퍼티를 설정하면 JWT로 인코딩한 Bearer 토큰을 검증하는 리소스 서버가 자동으로 설정된다.
  • OpenID Connect Provider 설정 엔드포인트 또는 인가 서버 메타데이터 엔드포인트를 검색해서 jwk-set-uri 엔드포인트를 찾아 검증을 실행한다.
  • 리소스 서버는 인가 서버의 jwk-set-uri 엔드포인트로 유효한 공개키를 질의하기 위한 검증 전략을 설정한다.
  • issuer-uri에 대한 각 JWT 클레임을 검증할 전략을 설정한다.
  1. 클라이언트가 Authorization Bearer token-value를 헤더에 담아서 요청한다.
  2. 리소스 서버는 요청한 토큰이 Bearer 토큰 사양에 부합하는지 검사한다.
  3. 인가 서버에서 JWT 토큰에 서명한 개인키와 매칭되는 공개키를 jwk-set-uri 엔드포인트 요청으로 가져와서 첫 번째 검증을 진행한다.
  4. JWT에 있는 exp, iss, nbf 등의 클레임의 정보가 기준에 부합하는지 두 번째 검증을 진행한다.
  5. 검증에 성공하면 Jwt 객체를 생성하고 클레임 정보에 있는 scope를 추출해서 시큐리티 권한에 매핑한다.
  6. Authentication 객체를 생성하고 Jwt 객체를 principal 속성에 저장한다.
  7. Authentication를 SecurityContext에 저장하고 인증을 완료한다.

📚 JwtDecoder

  • JwtDecoder는 문자열로 된 JWT(Json Web Token)를 Jwt 인스턴스로 디코딩하는 역할을 한다.
  • 기본 구현체로는 NimbusJwtDecoder가 있다.

검증 세부 흐름

  • JwtDecoder의 decode()를 통해 검증에 성공하면 최종적으로 Jwt 타입의 인증 객체를 반환한다.

JwtDecoder 생성 방법

  • JwtDecoders.fromIssuerLocation()을 호출하면 Provider 설정 또는 인가 서버 메타데이터 엔드포인트로 JWK 셋 Uri를 요청한다.
  • 애플리케이션에서 따로 정의한 JwtDecoder 빈이 없다면 스프링 부트가 디폴트 빈을 등록한다.
  • 기본적으로 스프링 부트에 의해 NimbusJwtDecoder 빈이 자동 생성될 경우 리소스 서버는 RS256을 사용한 토큰만 신뢰하고 이 토큰만 검증할 수 있다.
  • JwkSetUri에 의한 검증 방식으로 NimbusJwtDecoder를 생성할 경우 알고리즘 종류를 변경할순 있으나 RSA 알고리즘에 한해 변경이 가능하고 HMAC은 지원하지 않는다.