コア構成
Spring Boot サンプル
Spring Boot は、OAuth 2.0 ログインの完全な自動構成機能を提供します。
このセクションでは、Google を 認証プロバイダーとして使用して OAuth 2.0 ログインサンプル [GitHub] (英語) を構成する方法を示し、次のトピックについて説明します。
初期設定
ログインに Google の OAuth 2.0 認証システムを使用するには、Google API コンソールでプロジェクトを設定し、OAuth 2.0 資格情報を取得する必要があります。
認証用の Google の OAuth 2.0 実装 (英語) は OpenID Connect 1.0 (英語) 仕様に準拠しており、OpenID 認定 (英語) です。 |
「OAuth 2.0 のセットアップ」セクションから始めて、OpenID Connect (英語) ページの指示に従います。
「OAuth 2.0 資格情報の取得」の手順を完了すると、クライアント ID とクライアントシークレットで構成される資格情報を持つ新しい OAuth クライアントが作成されます。
リダイレクト URI の設定
リダイレクト URI は、エンドユーザーのユーザーエージェントが Google で認証され、同意 ページで OAuth クライアント ( 前の手順で作成された ) へのアクセスを許可した後にリダイレクトされるアプリケーション内のパスです。
「リダイレクト URI の設定」サブセクションで、承認されたリダイレクト URI フィールドが localhost:8080/login/oauth2/code/google
に設定されていることを確認します。
デフォルトのリダイレクト URI テンプレートは |
OAuth クライアントがプロキシサーバーの背後で実行されている場合は、プロキシサーバー構成をチェックして、アプリケーションが正しく構成されていることを確認する必要があります。また、 |
application.yml を設定します
Google を使用した新しい OAuth クライアントが作成されたため、認証フローに OAuth クライアントを使用するようにアプリケーションを構成する必要があります。そうするために:
application.yml
に移動して、次の構成を設定します。spring: security: oauth2: client: registration: (1) google: (2) client-id: google-client-id client-secret: google-client-secret
OAuth クライアントのプロパティ1 spring.security.oauth2.client.registration
は、OAuth クライアントプロパティの基本プロパティプレフィックスです。2 基本プロパティの接頭辞の後には、 ClientRegistration
の ID (Google など) が続きます。client-id
およびclient-secret
プロパティの値を、前に作成した OAuth 2.0 資格情報に置き換えます。
アプリケーションを起動します
Spring Boot サンプルを起動し、localhost:8080
に移動します。次に、デフォルトの自動生成ログインページにリダイレクトされ、Google へのリンクが表示されます。
Google リンクをクリックすると、認証のために Google にリダイレクトされます。
Google アカウントの資格情報で認証すると、同意 画面が表示されます。同意 画面では、前に作成した OAuth クライアントへのアクセスを認可するか拒否するかを尋ねられます。許可をクリックして、OAuth クライアントがメールアドレスと基本的なプロファイル情報にアクセスすることを承認します。
この時点で、OAuth クライアントは UserInfo エンドポイント (英語) からメールアドレスと基本プロファイル情報を取得し、認証済みセッションを確立します。
Spring Boot プロパティマッピング
次の表に、Spring Boot OAuth クライアントプロパティの ClientRegistration プロパティへのマッピングの概要を示します。
Spring Boot | ClientRegistration |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OpenID Connect プロバイダーの構成エンドポイント (英語) または認可サーバーのメタデータエンドポイント [IETF] (英語) の検出を使用して、 |
CommonOAuth2Provider
CommonOAuth2Provider
は、Google、GitHub、Facebook、Okta などの多くのよく知られたプロバイダーのデフォルトのクライアントプロパティのセットを事前定義します。
例: authorization-uri
、token-uri
、user-info-uri
は、プロバイダーにとって頻繁に変更されることはありません。必要な構成を減らすために、デフォルト値を提供することは理にかなっています。
前に示したように、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 (大文字と小文字を区別しない)と一致するため、クライアントプロパティの自動デフォルト設定はここでシームレスに機能します。 |
google-login
など、別の registrationId
を指定する場合は、provider
プロパティを構成することにより、クライアントプロパティの自動デフォルト設定を活用できます。
次のリストに例を示します。
spring:
security:
oauth2:
client:
registration:
google-login: (1)
provider: google (2)
client-id: google-client-id
client-secret: google-client-secret
1 | registrationId は google-login に設定されます。 |
2 | provider プロパティは google に設定され、CommonOAuth2Provider.GOOGLE.getBuilder() で設定されたクライアントプロパティの自動デフォルト設定を活用します。 |
カスタムプロバイダープロパティの構成
マルチテナンシーをサポートする OAuth 2.0 プロバイダーがいくつかあります。これにより、テナント(またはサブドメイン)ごとに異なるプロトコルエンドポイントが作成されます。
例: Okta に登録された OAuth クライアントは特定のサブドメインに割り当てられ、独自のプロトコルエンドポイントを持ちます。
これらの場合のために、Spring Boot はカスタムプロバイダープロパティを構成するための次の基本プロパティを提供します: spring.security.oauth2.client.provider.[providerId]
。
次のリストに例を示します。
spring:
security:
oauth2:
client:
registration:
okta:
client-id: okta-client-id
client-secret: okta-client-secret
provider:
okta: (1)
authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
user-name-attribute: sub
jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys
1 | 基本プロパティ(spring.security.oauth2.client.provider.okta )により、プロトコルエンドポイントの場所をカスタム構成できます。 |
Spring Boot 自動構成のオーバーライド
OAuth クライアントをサポートするための Spring Boot 自動構成クラスは OAuth2ClientAutoConfiguration
です。
次のタスクを実行します。
構成された OAuth クライアントプロパティからの
ClientRegistration
で構成されるClientRegistrationRepository
@Bean
を登録します。SecurityFilterChain
@Bean
を登録し、httpSecurity.oauth2Login()
を介して OAuth 2.0 ログインを有効にします。
特定の要件に基づいて自動構成をオーバーライドする必要がある場合、次の方法でオーバーライドできます。
ClientRegistrationRepository @Bean を登録する
次の例は、ClientRegistrationRepository
@Bean
を登録する方法を示しています。
Java
Kotlin
@Configuration
public class OAuth2LoginConfig {
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
}
private ClientRegistration googleClientRegistration() {
return ClientRegistration.withRegistrationId("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
.tokenUri("https://www.googleapis.com/oauth2/v4/token")
.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
.userNameAttributeName(IdTokenClaimNames.SUB)
.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
.clientName("Google")
.build();
}
}
@Configuration
class OAuth2LoginConfig {
@Bean
fun clientRegistrationRepository(): ClientRegistrationRepository {
return InMemoryClientRegistrationRepository(googleClientRegistration())
}
private fun googleClientRegistration(): ClientRegistration {
return ClientRegistration.withRegistrationId("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
.tokenUri("https://www.googleapis.com/oauth2/v4/token")
.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
.userNameAttributeName(IdTokenClaimNames.SUB)
.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
.clientName("Google")
.build()
}
}
SecurityFilterChain @Bean を登録する
次の例は、SecurityFilterChain
@Bean
を @EnableWebSecurity
に登録し、httpSecurity.oauth2Login()
を介して OAuth 2.0 ログインを有効にする方法を示しています。
Java
Kotlin
@Configuration
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
}
@Configuration
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeRequests {
authorize(anyRequest, authenticated)
}
oauth2Login { }
}
return http.build()
}
}
自動構成を完全にオーバーライドする
次の例は、ClientRegistrationRepository
@Bean
と SecurityFilterChain
@Bean
を登録することにより、自動構成を完全にオーバーライドする方法を示しています。
Java
Kotlin
@Configuration
public class OAuth2LoginConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
}
private ClientRegistration googleClientRegistration() {
return ClientRegistration.withRegistrationId("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
.tokenUri("https://www.googleapis.com/oauth2/v4/token")
.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
.userNameAttributeName(IdTokenClaimNames.SUB)
.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
.clientName("Google")
.build();
}
}
@Configuration
class OAuth2LoginConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeRequests {
authorize(anyRequest, authenticated)
}
oauth2Login { }
}
return http.build()
}
@Bean
fun clientRegistrationRepository(): ClientRegistrationRepository {
return InMemoryClientRegistrationRepository(googleClientRegistration())
}
private fun googleClientRegistration(): ClientRegistration {
return ClientRegistration.withRegistrationId("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
.tokenUri("https://www.googleapis.com/oauth2/v4/token")
.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
.userNameAttributeName(IdTokenClaimNames.SUB)
.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
.clientName("Google")
.build()
}
}
Spring Boot を使用しない Java 構成
Spring Boot を使用できず、CommonOAuth2Provider
の事前定義プロバイダーの 1 つ (Google など) を構成したい場合は、次の構成を適用します。
Java
Kotlin
XML
@Configuration
@EnableWebSecurity
public class OAuth2LoginConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
}
@Bean
public OAuth2AuthorizedClientService authorizedClientService(
ClientRegistrationRepository clientRegistrationRepository) {
return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
}
@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository(
OAuth2AuthorizedClientService authorizedClientService) {
return new AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService);
}
private ClientRegistration googleClientRegistration() {
return CommonOAuth2Provider.GOOGLE.getBuilder("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.build();
}
}
@Configuration
@EnableWebSecurity
open class OAuth2LoginConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeRequests {
authorize(anyRequest, authenticated)
}
oauth2Login { }
}
return http.build()
}
@Bean
open fun clientRegistrationRepository(): ClientRegistrationRepository {
return InMemoryClientRegistrationRepository(googleClientRegistration())
}
@Bean
open fun authorizedClientService(
clientRegistrationRepository: ClientRegistrationRepository?
): OAuth2AuthorizedClientService {
return InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository)
}
@Bean
open fun authorizedClientRepository(
authorizedClientService: OAuth2AuthorizedClientService?
): OAuth2AuthorizedClientRepository {
return AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService)
}
private fun googleClientRegistration(): ClientRegistration {
return CommonOAuth2Provider.GOOGLE.getBuilder("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.build()
}
}
<http auto-config="true">
<intercept-url pattern="/**" access="authenticated"/>
<oauth2-login authorized-client-repository-ref="authorizedClientRepository"/>
</http>
<client-registrations>
<client-registration registration-id="google"
client-id="google-client-id"
client-secret="google-client-secret"
provider-id="google"/>
</client-registrations>
<b:bean id="authorizedClientService"
class="org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService"
autowire="constructor"/>
<b:bean id="authorizedClientRepository"
class="org.springframework.security.oauth2.client.web.AuthenticatedPrincipalOAuth2AuthorizedClientRepository">
<b:constructor-arg ref="authorizedClientService"/>
</b:bean>