From 86824030f293838acbfe05bbf3072101d914d89c Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 22 Nov 2017 13:20:08 -0500 Subject: [PATCH] Update oauth2Login sample guide Fixes gh-4858 --- samples/boot/oauth2login/README.adoc | 717 ++++++++------------------- 1 file changed, 200 insertions(+), 517 deletions(-) diff --git a/samples/boot/oauth2login/README.adoc b/samples/boot/oauth2login/README.adoc index 7c42f2b66c..914b0b71a9 100644 --- a/samples/boot/oauth2login/README.adoc +++ b/samples/boot/oauth2login/README.adoc @@ -1,626 +1,309 @@ = OAuth 2.0 Login Sample -Joe Grandja -:toc: -:security-site-url: https://projects.spring.io/spring-security/ -[.lead] -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 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]. +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. +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 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: * <> * <> * <> * <> -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 <>. -** *web* -*** _MainController_ - the root controller that displays user information after a successful login. - -*org.springframework.boot.autoconfigure.security.oauth2.client* - -[circle] -* <> - a Spring Boot auto-configuration class - that automatically registers a _ClientRegistrationRepository_ bean in the _ApplicationContext_. -* <> - 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 <> for a detailed overview of the auto-configuration classes. - [[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 + +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 - 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]] -=== Register OAuth 2.0 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". -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"_*. - -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]] +[[google-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 -and have granted access to the OAuth Client _(created from the <>)_ on the *Consent screen* page. +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 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}"_*. - See <> for more details on this default. +TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`. + The *_registrationId_* is a unique identifier for the `ClientRegistration`. -[[google-login-configure-application-yml]] -=== Configuring application.yml +[[google-application-config]] +=== 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_. - -Go to *_src/main/resources_* and edit *application.yml*. Add the following configuration: +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 `application.yml` and set the following configuration: ++ [source,yaml] ---- -security: - oauth2: - client: - google: - client-id: ${client-id} - client-secret: ${client-secret} +spring: + security: + oauth2: + client: + registration: <1> + google: <2> + 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 <>. - -[TIP] -.OAuth client properties ++ +.OAuth Client properties ==== -. *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. - A list of these properties are detailed in <>. +<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 google. ==== -[[google-login-run-sample]] -=== Running the sample +. Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier. -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*. -The Consent screen will ask you to either *_Allow_* or *_Deny_* access to the OAuth Client you created in the previous step <>. -Click *_Allow_* to authorize the OAuth Client to access your _email address_ and _basic profile_ information. +After authenticating with your Google account credentials, the next page presented to you is the Consent screen. +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. -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_. -The home page will then be displayed showing the user attributes retrieved from the UserInfo Endpoint, for example, name, email, profile, sub, etc. +At this point, the OAuth Client retrieves your email address and basic profile information +from the http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint] and establishes an authenticated session. [[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 - https://tools.ietf.org/html/rfc6749#section-4.1[authorization code grant type]. - However, it *does not* implement the _OpenID Connect Core 1.0_ authorization code flow. +* <> +* <> +* <> -[[github-login-register-application]] +[[github-register-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 - and have granted access to the OAuth application on the *Authorize application* page. +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. -TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/login/oauth2/code/{registrationId}"_*. - See <> for more details on this default. +TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`. + 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]] -=== 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: +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: +. Go to `application.yml` and set the following configuration: ++ [source,yaml] ---- -security: - oauth2: - client: - github: - client-id: ${client-id} - client-secret: ${client-secret} +spring: + security: + oauth2: + client: + registration: <1> + github: <2> + 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 <>. +. 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] -.OAuth client properties -==== -. *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 <>. -==== - -[[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 <>. -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_]. +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]] -== 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_]. - The _login flow_ uses browser-based redirects, which essentially implements the https://tools.ietf.org/html/rfc6749#section-4.1[authorization code grant type]. - (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-login-register-application]] +[[facebook-register-application]] === 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 - and have granted access to the application on the *Authorize application* page. +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. -TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/login/oauth2/code/{registrationId}"_*. - See <> for more details on this default. +TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`. + 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]] -=== 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: +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: +. Go to `application.yml` and set the following configuration: ++ [source,yaml] ---- -security: - oauth2: - client: - facebook: - client-id: ${app-id} - client-secret: ${app-secret} +spring: + security: + oauth2: + client: + registration: <1> + facebook: <2> + 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 <>. - -[TIP] -.OAuth client properties ++ +.OAuth Client properties ==== -. *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.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 <>. +<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 facebook. ==== -[[facebook-login-run-sample]] -=== Running the sample +. Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier. -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*. -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_. +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. +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_. -The home page will then be displayed showing the user attributes retrieved from the UserInfo Endpoint, for example, id, name, etc. +At this point, the OAuth Client retrieves your personal user information +from the UserInfo Endpoint and establishes an authenticated session. [[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 - http://openid.net/connect/[OpenID Connect] specification and is http://openid.net/certification/[OpenID Certified]. +* <> +* <> +* <> +* <> -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-login-register-application]] +[[okta-register-application]] === Add Application -Sign in to your account _sub-domain_ and navigate to *_Applications -> Applications_* and then click on the _"Add Application"_ button. -From the _"Add Application"_ page, click on the _"Create New App"_ button and enter the following: +To use Okta's OAuth 2.0 authentication system for login, you must first https://www.okta.com/developer/signup[create a developer account]. + +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 * *Sign on method:* OpenID Connect -Click on 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 _"Configure OpenID Connect"_ page, enter *http://localhost:8080/login/oauth2/code/okta* for the field *Redirect URIs* and then click _"Finish"_. +Select the _Create_ 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 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 - and have granted access to the application on the *Authorize application* page. +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. -TIP: The default redirect URI is *_"{scheme}://{serverName}:{serverPort}/login/oauth2/code/{registrationId}"_*. - See <> for more details on this default. +TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`. + The *_registrationId_* is a unique identifier for the `ClientRegistration`. -The next page presented displays the _"General"_ tab selected for the application. -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]] +[[okta-assign-application-people]] === Assign Application to People -From the _"General"_ tab of the application, select the _"Assignments"_ tab and then click the _"Assign"_ button. -Select _"Assign to People"_ and assign your account to the application. Then click the _"Save and Go Back"_ 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 select the _Save and Go Back_ button. -[[okta-login-configure-application-yml]] -=== Configuring application.yml +[[okta-application-config]] +=== 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_. - -Go to *_src/main/resources_* and edit *application.yml*. Add the following configuration: +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 `application.yml` and set the following configuration: ++ [source,yaml] ---- -security: - oauth2: - client: - okta: - client-id: ${client-id} - client-secret: ${client-secret} - authorization-uri: https://${account-subdomain}.oktapreview.com/oauth2/v1/authorize - token-uri: https://${account-subdomain}.oktapreview.com/oauth2/v1/token - user-info-uri: https://${account-subdomain}.oktapreview.com/oauth2/v1/userinfo - jwk-set-uri: https://${account-subdomain}.oktapreview.com/oauth2/v1/keys +spring: + security: + oauth2: + client: + registration: <1> + okta: <2> + client-id: okta-client-id + client-secret: okta-client-secret + provider: <3> + okta: + 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 ---- - -Replace *${client-id}* and *${client-secret}* with the *client credentials* created in the previous section <>. -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 ++ +.OAuth Client properties ==== -. *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.okta*. -. 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 <>. +<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 okta. +<3> `spring.security.oauth2.client.provider` is the base property prefix for OAuth Provider properties. ==== -[[okta-login-run-sample]] -=== Running the sample +. Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier. +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*] -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. - -[[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 mapAuthorities(Collection authorities) { - Set 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 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-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, <> 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 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(); - } -} ----- +After authenticating with your Okta account credentials, the OAuth Client retrieves your email address and basic profile information +from the http://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint] and establishes an authenticated session.