스프링 시큐리티 공식 레퍼런스를 한글로 번역한 문서입니다.
전체 목차는 여기에 있습니다.
목차:
- 28.1. WebClient OAuth2 Setup
- 28.2. Implicit OAuth2AuthorizedClient
- 28.3. Explicit OAuth2AuthorizedClient
- 28.4. clientRegistrationId
이 문서에서 설명하는 내용은 리액티브 환경을 기준으로 설명한다. 서블릿 환경은 서블릿 환경에서 WebClient 통합하기 섹션을 참고해라.
스프링 프레임워크는 기본적으로 bearer 토큰 설정을 지원한다.
webClient.get()
.headers(h -> h.setBearerAuth(token))
...
스프링 시큐리티는 이 기능을 기반으로 아래와 같은 기능을 추가 지원한다:
- 스프링 시큐리티가 자동으로 만료된 토큰을 갱신한다 (refresh 토큰이 있다면).
- 액세스 토큰을 요청했지만 토큰이 없는 경우, 스프링 시큐리티가 자동으로 액세스 토큰을 요청한다.
authorization_code에선, 리다이렉션을 수행한 다음 기존 요청을 다시 이어가는 것까지 포함한다.client_credentials에선, 단순히 토큰을 요청하고 저장한다.
- 현재 사용자의 OAuth 토큰을 그대로 사용하거나, 사용할 토큰을 직접 명시할 수 있다.
28.1. WebClient OAuth2 Setup
가장 먼저 WebClient를 적절하게 설정해야 한다. 아래 코드는 완전한 리액티브 환경에서 WebClient를 설정하는 예시다:
@Bean
WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations,
ServerOAuth2AuthorizedClientRepository authorizedClients) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients);
// (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
// oauth.setDefaultOAuth2AuthorizedClient(true);
// (optional) set a default ClientRegistration.registrationId
// oauth.setDefaultClientRegistrationId("client-registration-id");
return WebClient.builder()
.filter(oauth)
.build();
}
28.2. Implicit OAuth2AuthorizedClient
위 설정에서 defaultOAuth2AuthorizedClient를 true로 설정했다면, oauth2Login(i.e. OIDC)으로 인증한 현재 사용자의 인증 정보를 사용해서 자동으로 액세스 토큰을 공급한다. 또는 defaultClientRegistrationId를 유효한 ClientRegistration id로 설정했다면, 클라이언트 등록 정보를 사용해서 액세스 토큰을 공급한다. 편리한 방식이긴 하지만, 모든 엔드포인트에 액세스 토큰이 필요한 게 아니라면 위험한 방법이다 (액세스 토큰이 필요 없는 엔드포인트에 액세스 토큰을 전송할 수 있다).
Mono<String> body = this.webClient
.get()
.uri(this.uri)
.retrieve()
.bodyToMono(String.class);
28.3. Explicit OAuth2AuthorizedClient
필요할 때만 요청 속성에 OAuth2AuthorizedClient를 명시하는 것도 가능하다. 아래 예제에선 스프링 웹플럭스나 스프링 MVC의 메소드 인자 리졸버로 OAuth2AuthorizedClient를 리졸브한다. 물론 OAuth2AuthorizedClient를 리졸브하는 방식이 중요한 건 아니다.
@GetMapping("/explicit")
Mono<String> explicit(@RegisteredOAuth2AuthorizedClient("client-id") OAuth2AuthorizedClient authorizedClient) {
return this.webClient
.get()
.uri(this.uri)
.attributes(oauth2AuthorizedClient(authorizedClient))
.retrieve()
.bodyToMono(String.class);
}
28.4. clientRegistrationId
아니면 요청 속성에 clientRegistrationId를 지정하는 것도 가능한데, 이렇게 하면 WebClient가 OAuth2AuthorizedClient를 찾아 바인딩한다. 해당 클라이언트를 찾을 수 없다면 자동으로 하나를 선택한다.
Mono<String> body = this.webClient
.get()
.uri(this.uri)
.attributes(clientRegistrationId("client-id"))
.retrieve()
.bodyToMono(String.class);
Next :
EnableReactiveMethodSecurity
리액티브 환경에서 스프링 시큐리티의 메소드 시큐리티를 설정하는 방법을 설명합니다. 공식 문서에 있는 "EnableReactiveMethodSecurity" 챕터를 한글로 번역한 문서입니다.
전체 목차는 여기에 있습니다.