|
| 1 | +[[how-to-social-login]] |
| 2 | += How-to: Authenticate using Social Login |
| 3 | +:index-link: ../how-to.html |
| 4 | +:docs-dir: .. |
| 5 | +:examples-dir: {docs-dir}/examples |
| 6 | +:samples-dir: {docs-dir}/../../../../samples |
| 7 | +:github-ref: main |
| 8 | +:github-base-url: https://github.com/spring-projects/spring-authorization-server/blob/{github-ref} |
| 9 | + |
| 10 | +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]. |
| 11 | +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]. |
| 12 | + |
| 13 | +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. |
| 14 | + |
| 15 | +* <<register-social-login-provider>> |
| 16 | +* <<configure-oauth2-login>> |
| 17 | +* <<advanced-use-cases>> |
| 18 | + |
| 19 | +[[register-social-login-provider]] |
| 20 | +== Register with Social Login Provider |
| 21 | + |
| 22 | +To get started, you will need to set up an application with your chosen social login provider. |
| 23 | +Common providers include: |
| 24 | + |
| 25 | +* https://developers.google.com/identity/openid-connect/openid-connect#appsetup[Google] |
| 26 | +* https://github.com/settings/developers[GitHub] |
| 27 | +* https://developers.facebook.com/apps[Facebook] |
| 28 | +* https://www.okta.com/developer/signup[Okta] |
| 29 | + |
| 30 | +Follow the steps for your provider until you are asked to specify a Redirect URI. |
| 31 | +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. |
| 32 | + |
| 33 | +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. |
| 34 | + |
| 35 | +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. |
| 36 | + |
| 37 | +Once you've completed the set-up process with your social login provider, you should have obtained credentials (a Client ID and Client Secret). |
| 38 | +In addition, you will need to reference the provider's documentation and take note of the following values: |
| 39 | + |
| 40 | +* **Authorization URI**: The endpoint that is used to initiate the `authorization_code` flow at the provider. |
| 41 | +* **Token URI**: The endpoint that is used to exchange an `authorization_code` for an `access_token` and optionally an `id_token`. |
| 42 | +* **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. |
| 43 | +* **User Info URI**: The endpoint that is used to obtain user information, which is required when an `id_token` is not available. |
| 44 | +* **User Name Attribute**: The claim in either the `id_token` or the User Info Response containing the username of the user. |
| 45 | + |
| 46 | +[[configure-oauth2-login]] |
| 47 | +== Configure OAuth 2.0 Login |
| 48 | + |
| 49 | +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]. |
| 50 | + |
| 51 | +* <<configure-oauth2-login-dependency>> |
| 52 | +* <<configure-oauth2-login-client-registration>> |
| 53 | +* <<configure-oauth2-login-authentication>> |
| 54 | + |
| 55 | +[[configure-oauth2-login-dependency]] |
| 56 | +=== Add OAuth2 Client Dependency |
| 57 | + |
| 58 | +First, add the following dependency: |
| 59 | + |
| 60 | +[[configure-oauth2-login-maven-dependency]] |
| 61 | +.Maven |
| 62 | +[source,xml,role="primary",subs="attributes,verbatim"] |
| 63 | +---- |
| 64 | +<dependency> |
| 65 | + <groupId>org.springframework.boot</groupId> |
| 66 | + <artifactId>spring-boot-starter-oauth2-client</artifactId> |
| 67 | +</dependency> |
| 68 | +---- |
| 69 | + |
| 70 | +[[configure-oauth2-login-gradle-dependency]] |
| 71 | +.Gradle |
| 72 | +[source,gradle,role="secondary",subs="attributes,verbatim"] |
| 73 | +---- |
| 74 | +implementation "org.springframework.boot:spring-boot-starter-oauth2-client" |
| 75 | +---- |
| 76 | + |
| 77 | +[[configure-oauth2-login-client-registration]] |
| 78 | +=== Register a Client |
| 79 | + |
| 80 | +Next, configure the `ClientRegistration` with the values obtained <<register-social-login-provider,earlier>>. |
| 81 | +Using Okta as an example, configure the following properties: |
| 82 | + |
| 83 | +[[configure-oauth2-login-okta-example]] |
| 84 | +.application.yml |
| 85 | +[source,yaml] |
| 86 | +---- |
| 87 | +include::{examples-dir}/src/main/java/sample/socialLogin/application.yml[] |
| 88 | +---- |
| 89 | + |
| 90 | +NOTE: The `registrationId` in the above example is `my-client`. |
| 91 | + |
| 92 | +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. |
| 93 | + |
| 94 | +This simple example demonstrates a typical configuration, but some providers will require additional configuration. |
| 95 | +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. |
| 96 | + |
| 97 | +[[configure-oauth2-login-authentication]] |
| 98 | +=== Configure Authentication |
| 99 | + |
| 100 | +Finally, to configure Spring Authorization Server to use a social login provider for authentication, you can use `oauth2Login()` instead of `formLogin()`. |
| 101 | +You can also automatically redirect an unauthenticated user to the provider by configuring `exceptionHandling()` with an `AuthenticationEntryPoint`. |
| 102 | + |
| 103 | +Continuing our <<configure-oauth2-login-okta-example,earlier example>>, configure Spring Security using a `@Configuration` as in the following example: |
| 104 | + |
| 105 | +.Configure OAuth 2.0 Login |
| 106 | +[source,java] |
| 107 | +---- |
| 108 | +include::{examples-dir}/src/main/java/sample/socialLogin/SecurityConfig.java[] |
| 109 | +---- |
| 110 | + |
| 111 | +<1> A Spring Security filter chain for the xref:protocol-endpoints.adoc[Protocol Endpoints]. |
| 112 | +<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]. |
| 113 | +<3> A Spring Security filter chain for https://docs.spring.io/spring-security/reference/servlet/authentication/index.html[authentication]. |
| 114 | +<4> Configure {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login] for authentication. |
| 115 | + |
| 116 | +If you configured a `UserDetailsService` when xref:{docs-dir}/getting-started.adoc#developing-your-first-application[getting started], you can remove it now. |
| 117 | + |
| 118 | +[[advanced-use-cases]] |
| 119 | +== Advanced Use Cases |
| 120 | + |
| 121 | +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. |
| 122 | +Select from the following use cases to see an example of each: |
| 123 | + |
| 124 | +* I want to <<advanced-use-cases-automatically-redirect>> |
| 125 | +* I want to <<advanced-use-cases-capture-users>> |
| 126 | +* I want to <<advanced-use-cases-map-claims>> |
| 127 | +* I want to <<advanced-use-cases-configurer>> |
| 128 | + |
| 129 | +[[advanced-use-cases-automatically-redirect]] |
| 130 | +=== Automatically Redirect to a Provider |
| 131 | + |
| 132 | +The following example `AuthenticationEntryPoint` uses a query parameter as a hint from the client to indicate which provider to automatically redirect to for authentication. |
| 133 | +For example, assuming Google is configured as a social login provider with a `registrationId` of `google`, a request to `/oauth2/authorize?idp=google&...` will redirect an unauthenticated user to `/oauth2/authorization/google` which will initiate logging in with Google: |
| 134 | + |
| 135 | +.`FederatedIdentityAuthenticationEntryPoint` |
| 136 | +[source,java] |
| 137 | +---- |
| 138 | +include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationEntryPoint.java[] |
| 139 | +---- |
| 140 | + |
| 141 | +[[advanced-use-cases-capture-users]] |
| 142 | +=== Capture Users in a Database |
| 143 | + |
| 144 | +The following example `AuthenticationSuccessHandler` uses a custom component to capture users in a local database when they first log in: |
| 145 | + |
| 146 | +.`FederatedIdentityAuthenticationSuccessHandler` |
| 147 | +[source,java] |
| 148 | +---- |
| 149 | +include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationSuccessHandler.java[] |
| 150 | +---- |
| 151 | + |
| 152 | +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. |
| 153 | +Here is an example that simply stores users in-memory: |
| 154 | + |
| 155 | +.`UserRepositoryOAuth2UserHandler` |
| 156 | +[source,java] |
| 157 | +---- |
| 158 | +include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/UserRepositoryOAuth2UserHandler.java[] |
| 159 | +---- |
| 160 | + |
| 161 | +[[advanced-use-cases-map-claims]] |
| 162 | +=== Map Claims to an ID Token |
| 163 | + |
| 164 | +The following example `OAuth2TokenCustomizer` maps a user's claims from an authentication provider to the `id_token` produced by Spring Authorization Server: |
| 165 | + |
| 166 | +.`FederatedIdentityIdTokenCustomizer` |
| 167 | +[source,java] |
| 168 | +---- |
| 169 | +include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityIdTokenCustomizer.java[] |
| 170 | +---- |
| 171 | + |
| 172 | +You can configure Spring Authorization Server to use this customizer by publishing it as a `@Bean` as in the following example: |
| 173 | + |
| 174 | +.Configure `FederatedIdentityIdTokenCustomizer` |
| 175 | +[source,java] |
| 176 | +---- |
| 177 | +@Bean |
| 178 | +public OAuth2TokenCustomizer<JwtEncodingContext> idTokenCustomizer() { |
| 179 | + return new FederatedIdentityIdTokenCustomizer(); |
| 180 | +} |
| 181 | +---- |
| 182 | + |
| 183 | +[[advanced-use-cases-configurer]] |
| 184 | +=== Create My Own Configurer |
| 185 | + |
| 186 | +The following example `SecurityConfigurer` combines configuration for all of the above examples into a single reusable component: |
| 187 | + |
| 188 | +.`FederatedIdentityConfigurer` |
| 189 | +[source,java] |
| 190 | +---- |
| 191 | +include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityConfigurer.java[] |
| 192 | +---- |
| 193 | + |
| 194 | +The configurer can be applied using the Spring Security DSL as in the following example: |
| 195 | + |
| 196 | +.Apply Configurer |
| 197 | +[source,java] |
| 198 | +---- |
| 199 | +http.apply(new FederatedIdentityConfigurer()); |
| 200 | +---- |
| 201 | + |
| 202 | +The configurer also has its own DSL to customize the defaults. |
| 203 | +Here's a full example: |
| 204 | + |
| 205 | +.Customize using Configurer |
| 206 | +[source,java] |
| 207 | +---- |
| 208 | +http.apply(new FederatedIdentityConfigurer()) |
| 209 | + .loginPageUrl("/social/login") |
| 210 | + .authorizationRequestUri("/social/login/{registrationId}") |
| 211 | + .oauth2UserHandler((oauth2User) -> { |
| 212 | + // TODO: Handle login of an OAuth2 user... |
| 213 | + }) |
| 214 | + .oidcUserHandler((oidcUser) -> { |
| 215 | + // TODO: Handle login of an OIDC user... |
| 216 | + }); |
| 217 | +---- |
0 commit comments