[[how-to-social-login]]
= How-to: Authenticate using Social Login
:index-link: ../how-to.html
:docs-dir: ..
:examples-dir: {docs-dir}/examples
:samples-dir: {docs-dir}/../../../../samples
:github-ref: main
:github-base-url: https://github.com/spring-projects/spring-authorization-server/blob/{github-ref}

This guide shows how to configure xref:{docs-dir}/index.adoc#top[Spring Authorization Server] with a social login provider (such as Google, GitHub, etc.) for {spring-security-reference-base-url}/servlet/authentication/index.html[authentication].
The purpose of this guide is to demonstrate how to replace {spring-security-reference-base-url}/servlet/authentication/passwords/form.html[Form Login] with {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login].

NOTE: Spring Authorization Server is built on {spring-security-reference-base-url}/index.html[Spring Security] and we will be using Spring Security concepts throughout this guide.

* <<register-social-login-provider>>
* <<configure-oauth2-login>>
* <<advanced-use-cases>>

[[register-social-login-provider]]
== Register with Social Login Provider

To get started, you will need to set up an application with your chosen social login provider.
Common providers include:

* https://developers.google.com/identity/openid-connect/openid-connect#appsetup[Google]
* https://github.com/settings/developers[GitHub]
* https://developers.facebook.com/apps[Facebook]
* https://www.okta.com/developer/signup[Okta]

Follow the steps for your provider until you are asked to specify a Redirect URI.
To set up a Redirect URI, choose a `registrationId` (such as `google`, `my-client` or any other unique identifier you wish) which you will use to configure both Spring Security **and** your provider.

NOTE: The `registrationId` is a unique identifier for the `ClientRegistration` in Spring Security. The default Redirect URI template is `\{baseUrl\}/login/oauth2/code/\{registrationId\}`. See {spring-security-reference-base-url}/servlet/oauth2/login/core.html#oauth2login-sample-redirect-uri[Setting the Redirect URI] in the Spring Security reference for more information.

TIP: For example, testing locally on port `9000` with a `registrationId` of `google`, your Redirect URI would be `http://localhost:9000/login/oauth2/code/google`. Enter this value as the Redirect URI when setting up the application with your provider.

Once you've completed the set-up process with your social login provider, you should have obtained credentials (a Client ID and Client Secret).
In addition, you will need to reference the provider's documentation and take note of the following values:

* **Authorization URI**: The endpoint that is used to initiate the `authorization_code` flow at the provider.
* **Token URI**: The endpoint that is used to exchange an `authorization_code` for an `access_token` and optionally an `id_token`.
* **JWK Set URI**: The endpoint that is used to obtain keys for verifying the signature of a JWT, which is required when an `id_token` is available.
* **User Info URI**: The endpoint that is used to obtain user information, which is required when an `id_token` is not available.
* **User Name Attribute**: The claim in either the `id_token` or the User Info Response containing the username of the user.

[[configure-oauth2-login]]
== Configure OAuth 2.0 Login

Once you've <<register-social-login-provider,registered>> with a social login provider, you can proceed to configuring Spring Security for {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login].

* <<configure-oauth2-login-dependency>>
* <<configure-oauth2-login-client-registration>>
* <<configure-oauth2-login-authentication>>

[[configure-oauth2-login-dependency]]
=== Add OAuth2 Client Dependency

First, add the following dependency:

[[configure-oauth2-login-maven-dependency]]
.Maven
[source,xml,role="primary",subs="attributes,verbatim"]
----
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
----

[[configure-oauth2-login-gradle-dependency]]
.Gradle
[source,gradle,role="secondary",subs="attributes,verbatim"]
----
implementation "org.springframework.boot:spring-boot-starter-oauth2-client"
----

[[configure-oauth2-login-client-registration]]
=== Register a Client

Next, configure the `ClientRegistration` with the values obtained <<register-social-login-provider,earlier>>.
Using Okta as an example, configure the following properties:

[[configure-oauth2-login-okta-example]]
.application.yml
[source,yaml]
----
include::{examples-dir}/src/main/java/sample/socialLogin/application.yml[]
----

NOTE: The `registrationId` in the above example is `my-client`.

TIP: The above example demonstrates the *recommended* way to set the Provider URL, Client ID and Client Secret using environment variables (`OKTA_BASE_URL`, `OKTA_CLIENT_ID` and `OKTA_CLIENT_SECRET`). See {spring-boot-reference-base-url}/features.html#features.external-config[Externalized Configuration] in the Spring Boot reference for more information.

This simple example demonstrates a typical configuration, but some providers will require additional configuration.
For more information about configuring the `ClientRegistration`, see {spring-security-reference-base-url}/servlet/oauth2/login/core.html#oauth2login-boot-property-mappings[Spring Boot Property Mappings] in the Spring Security reference.

[[configure-oauth2-login-authentication]]
=== Configure Authentication

Finally, to configure Spring Authorization Server to use a social login provider for authentication, you can use `oauth2Login()` instead of `formLogin()`.
You can also automatically redirect an unauthenticated user to the provider by configuring `exceptionHandling()` with an `AuthenticationEntryPoint`.

Continuing our <<configure-oauth2-login-okta-example,earlier example>>, configure Spring Security using a `@Configuration` as in the following example:

.Configure OAuth 2.0 Login
[source,java]
----
include::{examples-dir}/src/main/java/sample/socialLogin/SecurityConfig.java[]
----

<1> A Spring Security filter chain for the xref:{docs-dir}/protocol-endpoints.adoc[Protocol Endpoints].
<2> Configure an `AuthenticationEntryPoint` for redirecting to the {spring-security-reference-base-url}/servlet/oauth2/login/advanced.html#oauth2login-advanced-login-page[OAuth 2.0 Login endpoint].
<3> A Spring Security filter chain for https://docs.spring.io/spring-security/reference/servlet/authentication/index.html[authentication].
<4> Configure {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login] for authentication.

If you configured a `UserDetailsService` when xref:{docs-dir}/getting-started.adoc#developing-your-first-application[getting started], you can remove it now.

[[advanced-use-cases]]
== Advanced Use Cases

The https://github.com/spring-projects/spring-authorization-server/tree/{github-ref}/samples#demo-sample[demo authorization server sample^] demonstrates advanced configuration options for federating identity providers.
Select from the following use cases to see an example of each:

* I want to <<advanced-use-cases-capture-users>>
* I want to <<advanced-use-cases-map-claims>>

[[advanced-use-cases-capture-users]]
=== Capture Users in a Database

The following example `AuthenticationSuccessHandler` uses a custom component to capture users in a local database when they first log in:

.`FederatedIdentityAuthenticationSuccessHandler`
[source,java]
----
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationSuccessHandler.java[tags=imports;class]
----

Using the `AuthenticationSuccessHandler` above, you can plug in your own `Consumer<OAuth2User>` that can capture users in a database or other data store for concepts like Federated Account Linking or JIT Account Provisioning.
Here is an example that simply stores users in-memory:

.`UserRepositoryOAuth2UserHandler`
[source,java]
----
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/UserRepositoryOAuth2UserHandler.java[tags=imports;class]
----

[[advanced-use-cases-map-claims]]
=== Map Claims to an ID Token

The following example `OAuth2TokenCustomizer` maps a user's claims from an authentication provider to the `id_token` produced by Spring Authorization Server:

.`FederatedIdentityIdTokenCustomizer`
[source,java]
----
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityIdTokenCustomizer.java[tags=imports;class]
----

You can configure Spring Authorization Server to use this customizer by publishing it as a `@Bean` as in the following example:

.Configure `FederatedIdentityIdTokenCustomizer`
[source,java]
----
@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> idTokenCustomizer() {
    return new FederatedIdentityIdTokenCustomizer();
}
----
