OAuthClient
1. OAuth2 Client
1.1 OAuth2 Client 사용 사례
- OAuth 2.0 또는 OpenID Connect 1.0을 사용하여 사용자 로그인을 구현하고 싶은 경우
- 사용자를 위해 서드파티 API에 액세스하기 위한 액세스 토큰을 얻기 위해 RestClient를 사용하고 싶은 경우
- 사용자를 위해 서드파티 API에 액세스하기 위한 액세스 토큰을 얻기 위해 WebClient를 사용하고 싶은 경우
- 두 가지 모두 구현하고 싶은 경우 (사용자 로그인 그리고 서드파티 API 액세스)
1.2 의존성 추가
- OAuth2 Client를 시작하려면 프로젝트에 spring-security-oauth2-client 의존성을 추가하세요.
- Spring Boot를 사용하는 경우, 다음 스타터를 추가하면 됩니다.
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
2. OAuth2 Login
- OAuth 2.0 로그인 기능은 사용자가 OAuth 2.0 제공업체(GitHub 등)나 OpenID Connect 1.0 제공업체(Google 등)의 기존 계정을 사용하여 애플리케이션에 로그인할 수 있도록 지원합니다.
- "Google로 로그인" 또는 "GitHub로 로그인"과 같은 소셜 로그인 시나리오를 구현합니다.
- OAuth2 로그인은 OAuth2 클라이언트 기능 위에 구축된 상위 수준의 기능으로, 독립적으로 동작하지 않으며 OAuth2 클라이언트가 필수적으로 필요합니다.
- OAuth 2.0 인증 프레임워크와 OpenID Connect Core 1.0에서 명시된 Authorization Code Grant 플로우를 기반으로 구현됩니다.
2.1 Spring Boot 샘플
- Spring Boot는 OAuth 2.0 로그인을 위한 완전한 자동 구성 기능을 제공합니다.
- 이 섹션에서는 Google을 인증 제공업체로 사용하여 OAuth 2.0 로그인 샘플을 구성하는 방법을 설명합니다.
2.2 Google OAuth 2.0 로그인 설정
- 로그인을 위해 Google의 OAuth 2.0 인증 시스템을 사용하려면, OAuth 2.0 자격 증명을 얻기 위해 Google API Console에서 프로젝트를 설정해야 합니다.
- Google의 OAuth 2.0 구현은 OpenID Connect 1.0 사양을 준수하며 OpenID 인증을 받았습니다.
- 구글 콘솔에서 프로젝트 설정을 완료한 후, 클라이언트 ID와 클라이언트 시크릿으로 구성된 자격 증명을 가진 새로운 OAuth 클라이언트가 생성됩니다.
2.3 리다이렉트 URI 설정
- 리다이렉트 URI는 최종 사용자가 Google로 인증을 완료하고 동의 페이지에서 OAuth 클라이언트(이전 단계에서 생성)에 대한 액세스 권한을 부여한 후 사용자 에이전트가 다시 리다이렉트되는 애플리케이션 내의 경로입니다.
- "Set a redirect URI" 하위 섹션에서 Authorized redirect URIs 필드가 localhost:8080/login/oauth2/code/google로 설정되어 있는지 확인하세요.
- 기본 리다이렉트 URI 템플릿은
{baseUrl}/login/oauth2/code/{registrationId}입니다. registrationId는 ClientRegistration의 고유 식별자입니다. - OAuth 클라이언트가 프록시 서버 뒤에서 실행되는 경우, 애플리케이션이 올바르게 구성되었는지 확인하기 위해 프록시 서버 구성을 확인해야 합니다. 또한 redirect-uri에 지원되는 URI 템 플릿 변수들을 참조하세요.
2.4 application.yml 설정
spring:
security:
oauth2:
client:
registration:
google:
client-id: google-client-id
client-secret: google-client-secret
- 이제 Google과 함께 새로운 OAuth 클라이언트가 있으므로, 인증 플로우에 OAuth 클라이언트를 사용하도록 애플리케이션을 위와 같이 구성합니다.
- spring.security.oauth2.client.registration은 OAuth 클라이언트 속성의 기본 속성 접두사입니다.
- 기본 속성 접 두사 다음에는 Google과 같은 ClientRegistration의 ID가 옵니다.
- client-id와 client-secret 속성의 값을 앞서 생성한 OAuth 2.0 자격 증명으로 바꿔주세요.
2.5 애플리케이션 실행
- Spring Boot 샘플을 실행하고 localhost:8080으로 이동하세요.
- 그러면 기본 자동 생성된 로그인 페이지로 리다이렉트되며, 이 페이지에는 Google 링크가 표시됩니다.
- Google 링크를 클릭하면 인증을 위해 Google로 리다이렉트됩니다.
- Google 계정 자격 증명으로 인증한 후, 동의 화면이 표시됩니다.
- 동의 화면에서는 앞서 생성한 OAuth 클라이언트에 대한 액세스를 허용하거나 거부하도록 요청합니다. OAuth 클라이언트가 이메일 주소와 기본 프로필 정보에 액세스할 수 있도록 허용하려면 Allow를 클릭하세요.
- 이 시점에서 OAuth 클라이언트는 UserInfo 엔드포인트에서 이메일 주소와 기본 프로필 정보를 검색하고 인증된 세션을 설정합니다.
2.6 CommonOAuth2Provider
CommonOAuth2Provider는 널리 알려진 여러 제공업체(Google, GitHub, Facebook, Okta)에 대한 기본 클라이언트 속성 세트를 미리 정의합니다.- 예를 들어,
authorization-uri,token-uri,user-info-uri는 제공업체별로 자주 변경되지 않습니다. - 따 라서 기본값을 제공하여 필요한 구성을 줄이는 것이 합리적입니다.
2.6.1 기본 CommonOAuth2Provider 사용
- 앞에서 설명한 것처럼 Google 클라이언트를 구성할 때는
client-id와client-secret속성만 필요합니다.
spring:
security:
oauth2:
client:
registration:
google:
client-id: google-client-id
client-secret: google-client-secret
- 클라이언트 속성의 자동 기본값 설정은 registrationId(google)가 CommonOAuth2Provider의 GOOGLE enum과 일치하기 때문에 원활하게 작동합니다(대소문자 구분 안 함).
2.6.2 다른 registrationId 사용하기
- google-login과 같이 다른 registrationId를 지정하고 싶은 경우에도 provider 속성을 구성하여 클라이언트 속성의 자동 기본값 설정을 활용할 수 있습니다
spring:
security:
oauth2:
client:
registration:
google-login: # registrationId를 google-login으로 설정
provider: google # provider 속성을 google로 설정
client-id: google-client-id
client-secret: google-client-secret
- registrationId는 google-login으로 설정됩니다.
- provider 속성은 google로 설정되어 CommonOAuth2Provider.GOOGLE.getBuilder()에 설정된 클라이언트 속성의 자동 기본값 설정을 활용합니다.
- 이 방식을 사용하면 동일한 OAuth2 제공업체에 대해 여러 개의 다른 등록을 만들 수 있습니다.
- 예를 들어, 서로 다른 scope나 redirect-uri를 가진 여러 Google 로그인 옵션을 제공할 수 있습니다.
2.6.3 지원되는 CommonOAuth2Provider
- Spring Security는 다음과 같은 제공업체를 기본적으로 지원합니다:
- GOOGLE: Google OAuth2 로그인
- GITHUB: GitHub OAuth2 로그인
- FACEBOOK: Facebook OAuth2 로그인
- OKTA: Okta OAuth2/OIDC 로그인
- 각 제공업체에 대해 다음과 같은 기본값이 설정됩니다:
- Authorization URI
- Token URI
- User Info URI
- User Name Attribute Name
- Client Name
- Scopes (제공업체별로 다름)
3 OAuth2 Login 고급 설정
- 레퍼런스
- 앞서 보여준 OAuth2 Login 샘플을 사용하면 기본적인 OAuth2 로그인 기능을 구현할 수 있습니다.
- 기본적인 설정을 사용하면 대부분의 경우 충분하지만, 더 복잡한 요구 사항이 있는 경우 OAuth2 Login을 세밀하게 조정할 수 있습니다.
- HttpSecurity.oauth2Login() 메서드를 통해 OAuth 2.0 Login의 다양한 구성 옵션을 설정할 수 있습니다.
- 주요 구성 옵션들은 OAuth 2.0 프로토콜의 엔드포인트별로 그룹화되어 있어 직관적인 설정이 가능합니다.
3.1 OAuth 2.0 프로토콜 엔드포인트
- OAuth 2.0 Authorization Framework에서 정의하는 주요 엔드포인트는 다음과 같습니다.
- Authorization Endpoint: 클라이언트가 리소스 소유자로부터 인가를 받기 위해 사용하는 엔드포인트
- Token Endpoint: 클라이언트가 인가 코드를 액세스 토큰으로 교환하기 위해 사용하는 엔드포인트
- Redirection Endpoint: 인가 서버가 인가 결과를 클라이언트에게 반환하기 위해 사용하는 엔드포인트
- UserInfo Endpoint: 인증된 사용자에 대한 클레임 정보를 반환하는 OAuth 2.0 보호 리소스
3.2 OAuth 2.0 Login 구성 예시
@Configuration
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.oauth2Login(oauth2 -> oauth2
.authorizationEndpoint(authorization -> authorization
// Authorization Endpoint 설정
)
.redirectionEndpoint(redirection -> redirection
// Redirection Endpoint 설정
)
.tokenEndpoint(token -> token
// Token Endpoint 설정
)
.userInfoEndpoint(userInfo -> userInfo
// UserInfo Endpoint 설정
)
);
return http.build();
}
}
3.3 Redirection Endpoint 구성
3.3.1 기본 Redirection Endpoint
- Redirection Endpoint란 OAuth 2.0 인증 플로우에서 인가 서버가 인가 결과를 클라이언트에게 반환하는 엔드포인트입니다.
- OAuth 2.0 Login은 Authorization Code Grant를 활용하므로, 인가 자격 증명은 인가 코드입니다.
- 기본 Authorization Response baseUri는 /login/oauth2/code/*입니다.
3.3.2 커스텀 Redirection Endpoint 설정
@Configuration
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.oauth2Login(oauth2 -> oauth2
.redirectionEndpoint(redirection -> redirection
.baseUri("/login/oauth2/callback/*")
)
);
return http.build();
}
}
- 위 예시에서는 Redirection Endpoint의 baseUri를 /login/oauth2/callback/*로 설정했습니다.
- 위와 같이 커스텀하게 설정한 경우, ClientRegistration.redirectUri도 일치하도록 수정해야 합니다.
3.4 UserInfo Endpoint 고급 구성
4. OAuth2 Client 핵심 구성 요소
4.1 ClientRegistration
- ClientRegistration은 OAuth 2.0 Provider에 등록된 클라이언트의 정보를 담는 핵심 클래스입니다.
- 클라이언트 ID, 시크릿, 인증 방식, 리다이렉트 URI 등 OAuth2 통신에 필요한 모든 정보를 포함합니다.