Update oauth2Login sample guide

Fixes gh-4858
This commit is contained in:
Joe Grandja 2017-11-22 13:20:08 -05:00
parent 4f85f3a12f
commit 86824030f2
1 changed files with 200 additions and 517 deletions

View File

@ -1,626 +1,309 @@
= OAuth 2.0 Login Sample = OAuth 2.0 Login Sample
Joe Grandja
:toc:
:security-site-url: https://projects.spring.io/spring-security/
[.lead] This guide provides instructions on setting up the sample application with OAuth 2.0 Login using an OAuth 2.0 Provider or OpenID Connect 1.0 Provider.
This guide will walk you through the steps for setting up the sample application with OAuth 2.0 Login using an external _OAuth 2.0_ or _OpenID Connect 1.0_ Provider. The sample application uses Spring Boot 2.0.0.M6 and the `spring-security-oauth2-client` module which is new in Spring Security 5.0.
The sample application is built with *Spring Boot 1.5* and the *spring-security-oauth2-client* module that is new in {security-site-url}[Spring Security 5.0].
The following sections outline detailed steps for setting up OAuth 2.0 Login with these Providers: The following sections provide detailed steps for setting up OAuth 2.0 Login for these Providers:
* <<google-login, Google>> * <<google-login, Google>>
* <<github-login, GitHub>> * <<github-login, GitHub>>
* <<facebook-login, Facebook>> * <<facebook-login, Facebook>>
* <<okta-login, Okta>> * <<okta-login, Okta>>
NOTE: The _"authentication flow"_ is realized using the *Authorization Code Grant*, as specified in the https://tools.ietf.org/html/rfc6749#section-4.1[OAuth 2.0 Authorization Framework]
and http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[OpenID Connect Core 1.0] specifications.
[[sample-app-content]]
== Sample application content
The sample application contains the following package structure and artifacts:
*sample*
[circle]
* _OAuth2LoginApplication_ - the main class for the _Spring application_.
** *user*
*** _GitHubOAuth2User_ - a custom _OAuth2User_ for <<github-login, GitHub Login>>.
** *web*
*** _MainController_ - the root controller that displays user information after a successful login.
*org.springframework.boot.autoconfigure.security.oauth2.client*
[circle]
* <<client-registration-auto-configuration-class, _ClientRegistrationAutoConfiguration_>> - a Spring Boot auto-configuration class
that automatically registers a _ClientRegistrationRepository_ bean in the _ApplicationContext_.
* <<oauth2-login-auto-configuration-class, _OAuth2LoginAutoConfiguration_>> - a Spring Boot auto-configuration class that automatically enables OAuth 2.0 Login.
WARNING: The Spring Boot auto-configuration classes (and dependent resources) will eventually _live_ in the *Spring Boot Security Starter*.
NOTE: See <<oauth2-login-auto-configuration, OAuth 2.0 Login auto-configuration>> for a detailed overview of the auto-configuration classes.
[[google-login]] [[google-login]]
== Setting up *_Login with Google_* == Login with Google
The goal for this section of the guide is to setup login using Google as the _Authentication Provider_. This section shows how to configure the sample application using Google as the Authentication Provider and covers the following topics:
* <<google-initial-setup,Initial setup>>
* <<google-redirect-uri,Setting the redirect URI>>
* <<google-application-config,Configure application.yml>>
* <<google-boot-application,Boot up the application>>
[[google-initial-setup]]
=== Initial setup
To use Google's OAuth 2.0 authentication system for login, you must set up a project in the Google API Console to obtain OAuth 2.0 credentials.
NOTE: https://developers.google.com/identity/protocols/OpenIDConnect[Google's OAuth 2.0 implementation] for authentication conforms to the NOTE: https://developers.google.com/identity/protocols/OpenIDConnect[Google's OAuth 2.0 implementation] for authentication conforms to the
http://openid.net/connect/[OpenID Connect] specification and is http://openid.net/certification/[OpenID Certified]. http://openid.net/connect/[OpenID Connect 1.0] specification and is http://openid.net/certification/[OpenID Certified].
[[google-login-register-credentials]] Follow the instructions on the https://developers.google.com/identity/protocols/OpenIDConnect[OpenID Connect] page, starting in the section, "Setting up OAuth 2.0".
=== Register OAuth 2.0 credentials
In order to use Google's OAuth 2.0 authentication system for login, you must set up a project in the *Google API Console* to obtain OAuth 2.0 credentials. After completing the "Obtain OAuth 2.0 credentials" instructions, you should have a new OAuth Client with credentials consisting of a Client ID and a Client Secret.
Follow the instructions on the https://developers.google.com/identity/protocols/OpenIDConnect[OpenID Connect] page starting in the section *_"Setting up OAuth 2.0"_*. [[google-redirect-uri]]
After completing the sub-section, *_"Obtain OAuth 2.0 credentials"_*, you should have created a new *OAuth Client* with credentials consisting of a *Client ID* and *Client Secret*.
[[google-login-redirect-uri]]
=== Setting the redirect URI === Setting the redirect URI
The redirect URI is the path in the sample application that the end-user's user-agent is redirected back to after they have authenticated with Google The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Google
and have granted access to the OAuth Client _(created from the <<google-login-register-credentials, previous step>>)_ on the *Consent screen* page. and have granted access to the OAuth Client _(created in the previous step)_ on the Consent page.
For the sub-section, *_"Set a redirect URI"_*, ensure the *Authorised redirect URIs* is set to *http://localhost:8080/login/oauth2/code/google* In the "Set a redirect URI" sub-section, ensure that the *Authorized redirect URIs* field is set to `http://localhost:8080/login/oauth2/code/google`.
TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/login/oauth2/code/{registrationId}"_*. TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`.
See <<oauth2-client-properties, OAuth client properties>> for more details on this default. The *_registrationId_* is a unique identifier for the `ClientRegistration`.
[[google-login-configure-application-yml]] [[google-application-config]]
=== Configuring application.yml === Configure application.yml
Now that we have created a new OAuth Client with Google, we need to configure the sample application to use this OAuth Client for the _authentication flow_. Now that you have a new OAuth Client with Google, you need to configure the application to use the OAuth Client for the _authentication flow_. To do so:
Go to *_src/main/resources_* and edit *application.yml*. Add the following configuration:
. Go to `application.yml` and set the following configuration:
+
[source,yaml] [source,yaml]
---- ----
spring:
security: security:
oauth2: oauth2:
client: client:
google: registration: <1>
client-id: ${client-id} google: <2>
client-secret: ${client-secret} client-id: google-client-id
client-secret: google-client-secret
---- ----
+
Replace *${client-id}* and *${client-secret}* with the OAuth 2.0 credentials created in the previous section <<google-login-register-credentials, Register OAuth 2.0 credentials>>. .OAuth Client properties
[TIP]
.OAuth client properties
==== ====
. *security.oauth2.client* is the *_base property prefix_* for OAuth client properties. <1> `spring.security.oauth2.client.registration` is the base property prefix for OAuth Client properties.
. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.google*. <2> Following the base property prefix is the ID for the `ClientRegistration`, such as google.
. At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client.
A list of these properties are detailed in <<oauth2-client-properties, OAuth client properties>>.
==== ====
[[google-login-run-sample]] . Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier.
=== Running the sample
Launch the Spring Boot application by running *_sample.OAuth2LoginApplication_*. [[google-boot-application]]
=== Boot up the application
After the application successfully starts up, go to http://localhost:8080. You'll then be redirected to http://localhost:8080/login, which will display an _auto-generated login page_ with an anchor link for *Google*. Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Google.
Click through on the Google link and you'll be redirected to Google for authentication. Click on the Google link, and you are then redirected to Google for authentication.
After you authenticate using your Google credentials, the next page presented to you will be the *Consent screen*. After authenticating with your Google account credentials, the next page presented to you is the Consent screen.
The Consent screen will ask you to either *_Allow_* or *_Deny_* access to the OAuth Client you created in the previous step <<google-login-register-credentials, Register OAuth 2.0 credentials>>. The Consent screen asks you to either allow or deny access to the OAuth Client you created earlier.
Click *_Allow_* to authorize the OAuth Client to access your _email address_ and _basic profile_ information. Click *Allow* to authorize the OAuth Client to access your email address and basic profile information.
At this point, the OAuth Client will retrieve your email address and basic profile information from the http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[*UserInfo Endpoint*] and establish an _authenticated session_. At this point, the OAuth Client retrieves your email address and basic profile information
The home page will then be displayed showing the user attributes retrieved from the UserInfo Endpoint, for example, name, email, profile, sub, etc. from the http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint] and establishes an authenticated session.
[[github-login]] [[github-login]]
== Setting up *_Login with GitHub_* == Login with GitHub
The goal for this section of the guide is to setup login using GitHub as the _Authentication Provider_. This section shows how to configure the sample application using GitHub as the Authentication Provider and covers the following topics:
NOTE: https://developer.github.com/v3/oauth/[GitHub's OAuth 2.0 implementation] supports the standard * <<github-register-application,Register OAuth application>>
https://tools.ietf.org/html/rfc6749#section-4.1[authorization code grant type]. * <<github-application-config,Configure application.yml>>
However, it *does not* implement the _OpenID Connect Core 1.0_ authorization code flow. * <<github-boot-application,Boot up the application>>
[[github-login-register-application]] [[github-register-application]]
=== Register OAuth application === Register OAuth application
In order to use GitHub's OAuth 2.0 authentication system for login, you must https://github.com/settings/applications/new[_Register a new OAuth application_]. To use GitHub's OAuth 2.0 authentication system for login, you must https://github.com/settings/applications/new[Register a new OAuth application].
While registering your application, ensure the *Authorization callback URL* is set to *http://localhost:8080/login/oauth2/code/github*. When registering the OAuth application, ensure the *Authorization callback URL* is set to `http://localhost:8080/login/oauth2/code/github`.
NOTE: The *Authorization callback URL* (or redirect URI) is the path in the sample application that the end-user's user-agent is redirected back to after they have authenticated with GitHub The Authorization callback URL (redirect URI) is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with GitHub
and have granted access to the OAuth application on the *Authorize application* page. and have granted access to the OAuth application on the _Authorize application_ page.
TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/login/oauth2/code/{registrationId}"_*. TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`.
See <<oauth2-client-properties, OAuth client properties>> for more details on this default. The *_registrationId_* is a unique identifier for the `ClientRegistration`.
After completing the registration, you should have created a new *OAuth Application* with credentials consisting of a *Client ID* and *Client Secret*. [[github-application-config]]
=== Configure application.yml
[[github-login-configure-application-yml]] Now that you have a new OAuth application with GitHub, you need to configure the application to use the OAuth application for the _authentication flow_. To do so:
=== Configuring application.yml
Now that we have created a new OAuth application with GitHub, we need to configure the sample application to use this OAuth application (client) for the _authentication flow_.
Go to *_src/main/resources_* and edit *application.yml*. Add the following configuration:
. Go to `application.yml` and set the following configuration:
+
[source,yaml] [source,yaml]
---- ----
spring:
security: security:
oauth2: oauth2:
client: client:
github: registration: <1>
client-id: ${client-id} github: <2>
client-secret: ${client-secret} client-id: github-client-id
client-secret: github-client-secret
---- ----
+
.OAuth Client properties
====
<1> `spring.security.oauth2.client.registration` is the base property prefix for OAuth Client properties.
<2> Following the base property prefix is the ID for the `ClientRegistration`, such as github.
====
Replace *${client-id}* and *${client-secret}* with the OAuth 2.0 credentials created in the previous section <<github-login-register-application, Register OAuth application>>. . Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier.
[[github-boot-application]]
=== Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for GitHub.
Click on the GitHub link, and you are then redirected to GitHub for authentication.
After authenticating with your GitHub credentials, the next page presented to you is "Authorize application".
This page will ask you to *Authorize* the application you created in the previous step.
Click _Authorize application_ to allow the OAuth application to access your personal user data information.
At this point, the OAuth Client retrieves your personal user information
from the UserInfo Endpoint and establishes an authenticated session.
[TIP] [TIP]
.OAuth client properties For detailed information returned from the UserInfo Endpoint, see the API documentation
==== for https://developer.github.com/v3/users/#get-the-authenticated-user["Get the authenticated user"].
. *security.oauth2.client* is the *_base property prefix_* for OAuth client properties.
. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.github*.
. At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client.
A list of these properties are detailed in <<oauth2-client-properties, OAuth client properties>>.
====
[[github-login-run-sample]]
=== Running the sample
Launch the Spring Boot application by running *_sample.OAuth2LoginApplication_*.
After the application successfully starts up, go to http://localhost:8080. You'll then be redirected to http://localhost:8080/login, which will display an _auto-generated login page_ with an anchor link for *GitHub*.
Click through on the GitHub link and you'll be redirected to GitHub for authentication.
After you authenticate using your GitHub credentials, the next page presented to you is *Authorize application*.
This page will ask you to *Authorize* the application you created in the previous step <<github-login-register-application, Register OAuth application>>.
Click *_Authorize application_* to allow the OAuth application to access your _Personal user data_ information.
At this point, the OAuth application will retrieve your personal user information from the *UserInfo Endpoint* and establish an _authenticated session_.
The home page will then be displayed showing the user attributes retrieved from the UserInfo Endpoint, for example, id, name, email, login, etc.
TIP: For detailed information returned from the *UserInfo Endpoint* see the API documentation
for https://developer.github.com/v3/users/#get-the-authenticated-user[_Get the authenticated user_].
[[facebook-login]] [[facebook-login]]
== Setting up *_Login with Facebook_* == Login with Facebook
The goal for this section of the guide is to setup login using Facebook as the _Authentication Provider_. This section shows how to configure the sample application using Facebook as the Authentication Provider and covers the following topics:
NOTE: Facebook provides support for developers to https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow[_Manually Build a Login Flow_]. * <<facebook-register-application,Add a New App>>
The _login flow_ uses browser-based redirects, which essentially implements the https://tools.ietf.org/html/rfc6749#section-4.1[authorization code grant type]. * <<facebook-application-config,Configure application.yml>>
(NOTE: Facebook partially implements the _OAuth 2.0 Authorization Framework_, however, it *does not* implement the _OpenID Connect Core 1.0_ authorization code flow.) * <<facebook-boot-application,Boot up the application>>
[[facebook-login-register-application]] [[facebook-register-application]]
=== Add a New App === Add a New App
In order to use Facebook's OAuth 2.0 authentication system for login, you must first https://developers.facebook.com/apps[_Add a New App_]. To use Facebook's OAuth 2.0 authentication system for login, you must first https://developers.facebook.com/apps[Add a New App].
After clicking _"Create a New App"_, the _"Create a New App ID"_ page is presented. Enter the Display Name, Contact Email, Category and then click _"Create App ID"_. Select "Create a New App" and then the "Create a New App ID" page is presented. Enter the Display Name, Contact Email, Category and then click "Create App ID".
NOTE: The selection for the _Category_ field is not relevant but it's a required field - select _"Local"_. NOTE: The selection for the _Category_ field is not relevant but it's a required field - select "Local".
The next page presented is _"Product Setup"_. Click the _"Get Started"_ button for the *_Facebook Login_* product. In the left sidebar, under *_Products -> Facebook Login_*, select *_Settings_*. The next page presented is "Product Setup". Click the "Get Started" button for the *Facebook Login* product.
In the left sidebar, under _Products -> Facebook Login_, select _Settings_.
For the field *Valid OAuth redirect URIs*, enter *http://localhost:8080/login/oauth2/code/facebook* then click _"Save Changes"_. For the field *Valid OAuth redirect URIs*, enter `http://localhost:8080/login/oauth2/code/facebook` then click _Save Changes_.
NOTE: The *OAuth redirect URI* is the path in the sample application that the end-user's user-agent is redirected back to after they have authenticated with Facebook The OAuth redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Facebook
and have granted access to the application on the *Authorize application* page. and have granted access to the application on the _Authorize application_ page.
TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/login/oauth2/code/{registrationId}"_*. TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`.
See <<oauth2-client-properties, OAuth client properties>> for more details on this default. The *_registrationId_* is a unique identifier for the `ClientRegistration`.
Your application has now been assigned new OAuth 2.0 credentials under *App ID* and *App Secret*. [[facebook-application-config]]
=== Configure application.yml
[[facebook-login-configure-application-yml]] Now that you have created a new application with Facebook, you need to configure the sample application to use the application for the _authentication flow_. To do so:
=== Configuring application.yml
Now that we have created a new application with Facebook, we need to configure the sample application to use this application (client) for the _authentication flow_.
Go to *_src/main/resources_* and edit *application.yml*. Add the following configuration:
. Go to `application.yml` and set the following configuration:
+
[source,yaml] [source,yaml]
---- ----
spring:
security: security:
oauth2: oauth2:
client: client:
facebook: registration: <1>
client-id: ${app-id} facebook: <2>
client-secret: ${app-secret} client-id: facebook-client-id
client-secret: facebook-client-secret
---- ----
+
Replace *${app-id}* and *${app-secret}* with the OAuth 2.0 credentials created in the previous section <<facebook-login-register-application, Add a New App>>. .OAuth Client properties
[TIP]
.OAuth client properties
==== ====
. *security.oauth2.client* is the *_base property prefix_* for OAuth client properties. <1> `spring.security.oauth2.client.registration` is the base property prefix for OAuth Client properties.
. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.facebook*. <2> Following the base property prefix is the ID for the `ClientRegistration`, such as facebook.
. At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client.
A list of these properties are detailed in <<oauth2-client-properties, OAuth client properties>>.
==== ====
[[facebook-login-run-sample]] . Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier.
=== Running the sample
Launch the Spring Boot application by running *_sample.OAuth2LoginApplication_*. [[facebook-boot-application]]
=== Boot up the application
After the application successfully starts up, go to http://localhost:8080. You'll then be redirected to http://localhost:8080/login, which will display an _auto-generated login page_ with an anchor link for *Facebook*. Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Facebook.
Click through on the Facebook link and you'll be redirected to Facebook for authentication. Click on the Facebook link, and you are then redirected to Facebook for authentication.
After you authenticate using your Facebook credentials, the next page presented to you will be *Authorize application*. After authenticating with your Facebook credentials, the next page presented to you is "Authorize application".
This page will ask you to *Authorize* the application you created in the previous step <<facebook-login-register-application, Add a New App>>. This page will ask you to *Authorize* the application you created in the previous step.
Click *_Authorize application_* to allow the OAuth application to access your _public profile_ and _email address_. Click _Authorize application_ to allow the OAuth application to access your _public profile_ and _email address_ information.
At this point, the OAuth application will retrieve your personal user information from the *UserInfo Endpoint* and establish an _authenticated session_. At this point, the OAuth Client retrieves your personal user information
The home page will then be displayed showing the user attributes retrieved from the UserInfo Endpoint, for example, id, name, etc. from the UserInfo Endpoint and establishes an authenticated session.
[[okta-login]] [[okta-login]]
== Setting up *_Login with Okta_* == Login with Okta
The goal for this section of the guide is to setup login using Okta as the _Authentication Provider_. This section shows how to configure the sample application using Okta as the Authentication Provider and covers the following topics:
NOTE: http://developer.okta.com/docs/api/resources/oidc.html[Okta's OAuth 2.0 implementation] for authentication conforms to the * <<okta-register-application,Add Application>>
http://openid.net/connect/[OpenID Connect] specification and is http://openid.net/certification/[OpenID Certified]. * <<okta-assign-application-people,Assign Application to People>>
* <<okta-application-config,Configure application.yml>>
* <<okta-boot-application,Boot up the application>>
In order to use Okta's OAuth 2.0 authentication system for login, you must first https://www.okta.com/developer/signup[create a developer account]. [[okta-register-application]]
[[okta-login-register-application]]
=== Add Application === Add Application
Sign in to your account _sub-domain_ and navigate to *_Applications -> Applications_* and then click on the _"Add Application"_ button. To use Okta's OAuth 2.0 authentication system for login, you must first https://www.okta.com/developer/signup[create a developer account].
From the _"Add Application"_ page, click on the _"Create New App"_ button and enter the following:
Sign in to your account sub-domain and navigate to _Applications -> Applications_ and then select the "Add Application" button.
From the "Add Application" page, select the "Create New App" button and enter the following:
* *Platform:* Web * *Platform:* Web
* *Sign on method:* OpenID Connect * *Sign on method:* OpenID Connect
Click on the _"Create"_ button. Select the _Create_ button.
On the _"General Settings"_ page, enter the Application Name (for example, _"Spring Security Okta Login"_) and then click on the _"Next"_ button. On the "General Settings" page, enter the Application Name (for example, "Spring Security Okta Login") and then select the _Next_ button.
On the _"Configure OpenID Connect"_ page, enter *http://localhost:8080/login/oauth2/code/okta* for the field *Redirect URIs* and then click _"Finish"_. On the "Configure OpenID Connect" page, enter `http://localhost:8080/login/oauth2/code/okta` for the field *Redirect URIs* and then select _Finish_.
NOTE: The *Redirect URI* is the path in the sample application that the end-user's user-agent is redirected back to after they have authenticated with Okta The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Okta
and have granted access to the application on the *Authorize application* page. and have granted access to the application on the _Authorize application_ page.
TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/login/oauth2/code/{registrationId}"_*. TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`.
See <<oauth2-client-properties, OAuth client properties>> for more details on this default. The *_registrationId_* is a unique identifier for the `ClientRegistration`.
The next page presented displays the _"General"_ tab selected for the application. [[okta-assign-application-people]]
The _"General"_ tab displays the _"Settings"_ and _"Client Credentials"_ used by the application.
In the next step, we will _assign_ the application to _people_ in order to grant user(s) access to the application.
[[okta-login-assign-application-people]]
=== Assign Application to People === Assign Application to People
From the _"General"_ tab of the application, select the _"Assignments"_ tab and then click the _"Assign"_ button. From the "General" tab of the application, select the "Assignments" tab and then select the _Assign_ button.
Select _"Assign to People"_ and assign your account to the application. Then click the _"Save and Go Back"_ button. Select _Assign to People_ and assign your account to the application. Then select the _Save and Go Back_ button.
[[okta-login-configure-application-yml]] [[okta-application-config]]
=== Configuring application.yml === Configure application.yml
Now that we have created a new application with Okta, we need to configure the sample application (client) for the _authentication flow_. Now that you have created a new application with Okta, you need to configure the sample application to use the application for the _authentication flow_. To do so:
Go to *_src/main/resources_* and edit *application.yml*. Add the following configuration:
. Go to `application.yml` and set the following configuration:
+
[source,yaml] [source,yaml]
---- ----
spring:
security: security:
oauth2: oauth2:
client: client:
registration: <1>
okta: <2>
client-id: okta-client-id
client-secret: okta-client-secret
provider: <3>
okta: okta:
client-id: ${client-id} authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
client-secret: ${client-secret} token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
authorization-uri: https://${account-subdomain}.oktapreview.com/oauth2/v1/authorize user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
token-uri: https://${account-subdomain}.oktapreview.com/oauth2/v1/token user-name-attribute: sub
user-info-uri: https://${account-subdomain}.oktapreview.com/oauth2/v1/userinfo jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys
jwk-set-uri: https://${account-subdomain}.oktapreview.com/oauth2/v1/keys
---- ----
+
Replace *${client-id}* and *${client-secret}* with the *client credentials* created in the previous section <<okta-login-register-application, Add Application>>. .OAuth Client properties
As well, replace *${account-subdomain}* in _authorization-uri_, _token-uri_, _user-info-uri_ and _jwk-set-uri_ with the *sub-domain* assigned to your account during the registration process.
[TIP]
.OAuth client properties
==== ====
. *security.oauth2.client* is the *_base property prefix_* for OAuth client properties. <1> `spring.security.oauth2.client.registration` is the base property prefix for OAuth Client properties.
. Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.okta*. <2> Following the base property prefix is the ID for the `ClientRegistration`, such as okta.
. At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client. <3> `spring.security.oauth2.client.provider` is the base property prefix for OAuth Provider properties.
A list of these properties are detailed in <<oauth2-client-properties, OAuth client properties>>.
==== ====
[[okta-login-run-sample]] . Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier.
=== Running the sample As well, replace `https://your-subdomain.oktapreview.com` in `authorization-uri`, `token-uri`, `user-info-uri` and `jwk-set-uri` with the sub-domain assigned to your account during the registration process.
Launch the Spring Boot application by running *_sample.OAuth2LoginApplication_*. [[okta-boot-application]]
=== Boot up the application
After the application successfully starts up, go to http://localhost:8080. You'll then be redirected to http://localhost:8080/login, which will display an _auto-generated login page_ with an anchor link for *Okta*. Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Okta.
Click through on the Okta link and you'll be redirected to Okta for authentication. Click on the Okta link, and you are then redirected to Okta for authentication.
After you authenticate using your Okta credentials, the OAuth Client (application) will retrieve your email address and basic profile information from the http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[*UserInfo Endpoint*] After authenticating with your Okta account credentials, the OAuth Client retrieves your email address and basic profile information
and establish an _authenticated session_. The home page will then be displayed showing the user attributes retrieved from the UserInfo Endpoint, for example, name, email, profile, sub, etc. from the http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint] and establishes an authenticated session.
[[user-authority-mapping]]
== Mapping User Authorities
After the user successfully authenticates with the _OAuth 2.0 Provider_, the `OAuth2User.getAuthorities()` may be re-mapped to a new set of `GrantedAuthority`(s), which is then supplied to the `OAuth2AuthenticationToken`.
The `GrantedAuthority`(s) associated to the `OAuth2AuthenticationToken` is then used for authorizing requests, such as, `hasRole('USER') or hasRole('ADMIN')`.
In order to implement custom user authority mapping, you need to provide an implementation of `GrantedAuthoritiesMapper` and configure it using `OAuth2LoginConfigurer`.
The following is a partial implementation of `GrantedAuthoritiesMapper` that maps an `OidcUserAuthority` or `OAuth2UserAuthority` to a set of `GrantedAuthority`(s):
[source,java]
----
public class CustomGrantedAuthoritiesMapper implements GrantedAuthoritiesMapper {
@Override
public Collection<? extends GrantedAuthority> mapAuthorities(Collection<? extends GrantedAuthority> authorities) {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
for (GrantedAuthority authority : authorities) {
if (OidcUserAuthority.class.isInstance(authority)) {
OidcUserAuthority userAuthority = (OidcUserAuthority)authority;
IdToken idToken = userAuthority.getIdToken();
UserInfo userInfo = userAuthority.getUserInfo();
// TODO
// Map the claims found in IdToken and/or UserInfo
// to one or more GrantedAuthority's and add to mappedAuthorities
} else if (OAuth2UserAuthority.class.isInstance(authority)) {
OAuth2UserAuthority userAuthority = (OAuth2UserAuthority)authority;
Map<String, Object> userAttributes = userAuthority.getAttributes();
// TODO
// Map the attributes found in userAttributes
// to one or more GrantedAuthority's and add to mappedAuthorities
}
}
return mappedAuthorities;
}
}
----
The following _security configuration_ configures a custom `GrantedAuthoritiesMapper` for OAuth 2.0 Login:
[source,java]
----
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
.userAuthoritiesMapper(new CustomGrantedAuthoritiesMapper());
}
}
----
[[oauth2-login-auto-configuration]]
== OAuth 2.0 Login auto-configuration
As you worked through this guide and setup OAuth 2.0 Login with one of the Providers,
we hope you noticed the ease in configuration and setup required in getting the sample up and running?
And you may be asking, how does this all work? Thanks to some Spring Boot auto-configuration _magic_,
we were able to automatically register the OAuth Client(s) configured in the `Environment`,
as well, provide a minimal security configuration for OAuth 2.0 Login.
The following provides an overview of the Spring Boot auto-configuration classes:
[[client-registration-auto-configuration-class]]
*_org.springframework.boot.autoconfigure.security.oauth2.client.ClientRegistrationAutoConfiguration_*::
`ClientRegistrationAutoConfiguration` is responsible for registering a `ClientRegistrationRepository` _bean_ with the `ApplicationContext`.
The `ClientRegistrationRepository` is composed of one or more `ClientRegistration` instances, which are created from the OAuth client properties
configured in the `Environment` that are prefixed with `security.oauth2.client.registrations.[registration-id]`, for example, `security.oauth2.client.registrations.google`.
NOTE: `ClientRegistrationAutoConfiguration` also loads a _resource_ named *oauth2-clients-defaults.yml*,
which provides a set of default client property values for a number of _well-known_ Providers.
More on this in the later section <<oauth2-default-client-properties, Default client property values>>.
[[oauth2-login-auto-configuration-class]]
*_org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2LoginAutoConfiguration_*::
`OAuth2LoginAutoConfiguration` is responsible for enabling OAuth 2.0 Login,
only if there is a `ClientRegistrationRepository` _bean_ available in the `ApplicationContext`.
WARNING: The auto-configuration classes (and dependent resources) will eventually _live_ in the *Spring Boot Security Starter*.
[[oauth2-client-properties]]
=== OAuth client properties
The following specifies the common set of properties available for configuring an OAuth Client.
[TIP]
====
- *security.oauth2.client* is the *_base property prefix_* for OAuth client properties.
- Just below the *_base property prefix_* is the *_client property key_*, for example *security.oauth2.client.registrations.google*.
- At the base of the *_client property key_* are the properties for specifying the configuration for an OAuth Client.
====
- *client-authentication-method* - the method used to authenticate the _Client_ with the _Provider_. Supported values are *basic* and *post*.
- *authorized-grant-type* - the OAuth 2.0 Authorization Framework defines the https://tools.ietf.org/html/rfc6749#section-1.3.1[Authorization Code] grant type,
which is used to realize the _"authentication flow"_. Currently, this is the only supported grant type.
- *redirect-uri* - this is the client's _registered_ redirect URI that the _Authorization Server_ redirects the end-user's user-agent
to after the end-user has authenticated and authorized access for the client.
NOTE: The default redirect URI is _"{scheme}://{serverName}:{serverPort}/login/oauth2/code/{registrationId}"_, which leverages *URI template variables*.
- *scope* - a comma-delimited string of scope(s) requested during the _Authorization Request_ flow, for example: _openid, email, profile_
NOTE: _OpenID Connect Core 1.0_ defines these http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims[standard scope]: _profile, email, address, phone_
NOTE: Non-standard scope may be defined by a standard _OAuth 2.0 Provider_. Please consult the Provider's OAuth API documentation to learn which scope are supported.
- *authorization-uri* - the URI used by the client to redirect the end-user's user-agent to the _Authorization Server_ in order to obtain authorization from the end-user (the _Resource Owner_).
- *token-uri* - the URI used by the client when exchanging an _Authorization Grant_ (for example, Authorization Code) for an _Access Token_ at the _Authorization Server_.
- *user-info-uri* - the URI used by the client to access the protected resource *UserInfo Endpoint*, in order to obtain attributes of the end-user.
- *jwk-set-uri* - the URI used to retrieve the https://tools.ietf.org/html/rfc7517[JSON Web Key (JWK)] `Set`,
which contains cryptographic key(s) that are used to verify the https://tools.ietf.org/html/rfc7515[JSON Web Signature (JWS)] of the *ID Token* and optionally the *UserInfo Endpoint* response.
- *user-name-attribute-name* - the name of the attribute returned in the *UserInfo Endpoint* response that references the *Name* of the end-user.
NOTE: _OpenID Connect Core 1.0_ defines the http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims[_name_ Claim], which is the end-user's full name and is the default used for `DefaultOidcUser`.
IMPORTANT: Standard _OAuth 2.0 Provider's_ may vary the naming of their *Name* attribute. Please consult the Provider's *UserInfo* API documentation.
This is a *_required_* property for `DefaultOAuth2User`.
- *client-name* - this is a descriptive name used for the client. The name may be used in certain scenarios, for example, when displaying the name of the client in the _auto-generated login page_.
- *registration-id* - an _id_ which uniquely identifies the client registration. It *must be* unique within a `ClientRegistrationRepository`.
[[oauth2-default-client-properties]]
=== Default client property values
As noted previously, <<client-registration-auto-configuration-class, `ClientRegistrationAutoConfiguration`>> loads a _resource_ named *oauth2-clients-defaults.yml*,
which provides a set of default client property values for a number of _well-known_ Providers.
For example, the *authorization-uri*, *token-uri*, *user-info-uri* rarely change for a Provider and therefore it makes sense to
provide a set of defaults in order to reduce the configuration required by the user.
Below are the current set of default client property values:
.oauth2-clients-defaults.yml
[source,yaml]
----
security:
oauth2:
client:
google:
client-authentication-method: basic
authorized-grant-type: authorization_code
redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{registrationId}"
scope: openid, email, profile
authorization-uri: "https://accounts.google.com/o/oauth2/auth"
token-uri: "https://accounts.google.com/o/oauth2/token"
user-info-uri: "https://www.googleapis.com/oauth2/v3/userinfo"
jwk-set-uri: https://www.googleapis.com/oauth2/v3/certs
client-name: Google
github:
client-authentication-method: basic
authorized-grant-type: authorization_code
redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{registrationId}"
scope: user
authorization-uri: "https://github.com/login/oauth/authorize"
token-uri: "https://github.com/login/oauth/access_token"
user-info-uri: "https://api.github.com/user"
client-name: GitHub
facebook:
client-authentication-method: post
authorized-grant-type: authorization_code
redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{registrationId}"
scope: public_profile, email
authorization-uri: "https://www.facebook.com/v2.8/dialog/oauth"
token-uri: "https://graph.facebook.com/v2.8/oauth/access_token"
user-info-uri: "https://graph.facebook.com/me"
client-name: Facebook
okta:
client-authentication-method: basic
authorized-grant-type: authorization_code
redirect-uri: "{scheme}://{serverName}:{serverPort}{baseAuthorizeUri}/{registrationId}"
scope: openid, email, profile
client-name: Okta
----
= Appendix
'''
[[configure-non-spring-boot-app]]
== Configuring a _Non-Spring-Boot_ application
If you are not using Spring Boot for your application, you will not be able to leverage the auto-configuration features for OAuth 2.0 Login.
You will be required to provide your own _security configuration_ in order to enable OAuth 2.0 Login.
The following sample code demonstrates a minimal security configuration for enabling OAuth 2.0 Login.
Let's assume we have a _properties file_ named *oauth2-clients.properties* on the _classpath_ and it specifies all the _required_ properties for an OAuth Client, specifically _Google_.
.oauth2-clients.properties
[source,properties]
----
security.oauth2.client.registrations.google.client-id=${client-id}
security.oauth2.client.registrations.google.client-secret=${client-secret}
security.oauth2.client.registrations.google.client-authentication-method=basic
security.oauth2.client.registrations.google.authorized-grant-type=authorization_code
security.oauth2.client.registrations.google.redirect-uri=http://localhost:8080/login/oauth2/code/google
security.oauth2.client.registrations.google.scope=openid,email,profile
security.oauth2.client.registrations.google.authorization-uri=https://accounts.google.com/o/oauth2/auth
security.oauth2.client.registrations.google.token-uri=https://accounts.google.com/o/oauth2/token
security.oauth2.client.registrations.google.user-info-uri=https://www.googleapis.com/oauth2/v3/userinfo
security.oauth2.client.registrations.google.jwk-set-uri=https://www.googleapis.com/oauth2/v3/certs
security.oauth2.client.registrations.google.client-name=Google
----
The following _security configuration_ will enable OAuth 2.0 Login using _Google_ as the _Authentication Provider_:
[source,java]
----
@EnableWebSecurity
@PropertySource("classpath:oauth2-clients.properties")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private Environment environment;
public SecurityConfig(Environment environment) {
this.environment = environment;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
.clients(clientRegistrationRepository());
}
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
List<ClientRegistration> clientRegistrations = Collections.singletonList(
clientRegistration("security.oauth2.client.registrations.google."));
return new InMemoryClientRegistrationRepository(clientRegistrations);
}
private ClientRegistration clientRegistration(String clientPropertyKey) {
String registrationId = this.environment.getProperty(clientPropertyKey + "registration-id");
String clientId = this.environment.getProperty(clientPropertyKey + "client-id");
String clientSecret = this.environment.getProperty(clientPropertyKey + "client-secret");
ClientAuthenticationMethod clientAuthenticationMethod = new ClientAuthenticationMethod(
this.environment.getProperty(clientPropertyKey + "client-authentication-method"));
AuthorizationGrantType authorizationGrantType = AuthorizationGrantType.valueOf(
this.environment.getProperty(clientPropertyKey + "authorized-grant-type").toUpperCase());
String redirectUri = this.environment.getProperty(clientPropertyKey + "redirect-uri");
String[] scope = this.environment.getProperty(clientPropertyKey + "scope").split(",");
String authorizationUri = this.environment.getProperty(clientPropertyKey + "authorization-uri");
String tokenUri = this.environment.getProperty(clientPropertyKey + "token-uri");
String userInfoUri = this.environment.getProperty(clientPropertyKey + "user-info-uri");
String jwkSetUri = this.environment.getProperty(clientPropertyKey + "jwk-set-uri");
String clientName = this.environment.getProperty(clientPropertyKey + "client-name");
return new ClientRegistration.Builder(registrationId)
.clientId(clientId)
.clientSecret(clientSecret)
.clientAuthenticationMethod(clientAuthenticationMethod)
.authorizedGrantType(authorizationGrantType)
.redirectUri(redirectUri)
.scope(scope)
.authorizationUri(authorizationUri)
.tokenUri(tokenUri)
.userInfoUri(userInfoUri)
.jwkSetUri(jwkSetUri)
.clientName(clientName)
.build();
}
}
----