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 클레임을 검증할 전략을 설정한다.
- 클라이언트가 Authorization Bearer token-value를 헤더에 담아서 요청한다.
- 리소스 서버는 요청한 토큰이 Bearer 토큰 사양에 부합하는지 검사한다.
- 인가 서버에서 JWT 토큰에 서명한 개인키와 매칭되는 공개키를
jwk-set-uri 엔드포인트 요청으로 가져와서 첫 번째 검증을 진행한다.
- JWT에 있는 exp, iss, nbf 등의 클레임의 정보가 기준에 부합하는지 두 번째 검증을 진행한다.
- 검증에 성공하면 Jwt 객체를 생성하고 클레임 정보에 있는 scope를 추출해서 시큐리티 권한에 매핑한다.
- Authentication 객체를 생성하고 Jwt 객체를 principal 속성에 저장한다.
- 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은 지원하지 않는다.