123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- [[webflux-oauth2-login]]
- = OAuth 2.0 Login
- The OAuth 2.0 Login feature provides an application with the capability to have users log in to the application by using their existing account at an OAuth 2.0 Provider (e.g.
- GitHub) or OpenID Connect 1.0 Provider (such as Google).
- OAuth 2.0 Login implements the use cases: "Login with Google" or "Login with GitHub".
- NOTE: OAuth 2.0 Login is implemented by using the *Authorization Code Grant*, as specified in the https://tools.ietf.org/html/rfc6749#section-4.1[OAuth 2.0 Authorization Framework] and https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[OpenID Connect Core 1.0].
- [[webflux-oauth2-login-sample]]
- == Spring Boot 2.0 Sample
- Spring Boot 2.0 brings full auto-configuration capabilities for OAuth 2.0 Login.
- This section shows how to configure the {gh-samples-url}/reactive/webflux/java/oauth2/login[*OAuth 2.0 Login WebFlux sample*] using _Google_ as the _Authentication Provider_ and covers the following topics:
- * <<webflux-oauth2-login-sample-setup,Initial setup>>
- * <<webflux-oauth2-login-sample-redirect,Setting the redirect URI>>
- * <<webflux-oauth2-login-sample-config,Configure `application.yml`>>
- * <<webflux-oauth2-login-sample-start,Boot up the application>>
- [[webflux-oauth2-login-sample-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 https://openid.net/connect/[OpenID Connect 1.0] specification and is https://openid.net/certification/[OpenID Certified].
- 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 "Obtain OAuth 2.0 credentials" instructions, you should have a new OAuth Client with credentials consisting of a Client ID and a Client Secret.
- [[webflux-oauth2-login-sample-redirect]]
- === Setting the redirect URI
- 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 _(<<webflux-oauth2-login-sample-setup,created in the previous step>>)_ on the Consent page.
- 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 template is `+{baseUrl}/login/oauth2/code/{registrationId}+`.
- The *_registrationId_* is a unique identifier for the xref:servlet/oauth2/oauth2-client.adoc#oauth2Client-client-registration[ClientRegistration].
- For our example, the `registrationId` is `google`.
- IMPORTANT: If the OAuth Client is running behind a proxy server, it is recommended to check xref:features/exploits/http.adoc#http-proxy-server[Proxy Server Configuration] to ensure the application is correctly configured.
- Also, see the supported xref:servlet/oauth2/oauth2-client.adoc#oauth2Client-auth-code-redirect-uri[ `URI` template variables] for `redirect-uri`.
- [[webflux-oauth2-login-sample-config]]
- === Configure `application.yml`
- 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]
- ----
- spring:
- security:
- oauth2:
- client:
- registration: <1>
- google: <2>
- client-id: google-client-id
- client-secret: google-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 xref:servlet/oauth2/oauth2-client.adoc#oauth2Client-client-registration[ClientRegistration], such as google.
- ====
- . Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials you created earlier.
- [[webflux-oauth2-login-sample-start]]
- === 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 Google.
- Click on the Google link, and you are then redirected to Google for authentication.
- 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 retrieves your email address and basic profile information from the https://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint] and establishes an authenticated session.
- [[webflux-oauth2-login-openid-provider-configuration]]
- == Using OpenID Provider Configuration
- For well known providers, Spring Security provides the necessary defaults for the OAuth Authorization Provider's configuration.
- If you are working with your own Authorization Provider that supports https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[OpenID Provider Configuration] or https://tools.ietf.org/html/rfc8414#section-3[Authorization Server Metadata], the https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse[OpenID Provider Configuration Response]'s `issuer-uri` can be used to configure the application.
- [source,yml]
- ----
- spring:
- security:
- oauth2:
- client:
- provider:
- keycloak:
- issuer-uri: https://idp.example.com/auth/realms/demo
- registration:
- keycloak:
- client-id: spring-security
- client-secret: 6cea952f-10d0-4d00-ac79-cc865820dc2c
- ----
- The `issuer-uri` instructs Spring Security to query in series the endpoints `https://idp.example.com/auth/realms/demo/.well-known/openid-configuration`, `https://idp.example.com/.well-known/openid-configuration/auth/realms/demo`, or `https://idp.example.com/.well-known/oauth-authorization-server/auth/realms/demo` to discover the configuration.
- [NOTE]
- Spring Security will query the endpoints one at a time, stopping at the first that gives a 200 response.
- The `client-id` and `client-secret` are linked to the provider because `keycloak` is used for both the provider and the registration.
- [[webflux-oauth2-login-explicit]]
- == Explicit OAuth2 Login Configuration
- A minimal OAuth2 Login configuration is shown below:
- .Minimal OAuth2 Login
- ====
- .Java
- [source,java,role="primary"]
- ----
- @Bean
- ReactiveClientRegistrationRepository clientRegistrations() {
- ClientRegistration clientRegistration = ClientRegistrations
- .fromIssuerLocation("https://idp.example.com/auth/realms/demo")
- .clientId("spring-security")
- .clientSecret("6cea952f-10d0-4d00-ac79-cc865820dc2c")
- .build();
- return new InMemoryReactiveClientRegistrationRepository(clientRegistration);
- }
- @Bean
- SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
- http
- // ...
- .oauth2Login(withDefaults());
- return http.build();
- }
- ----
- .Kotlin
- [source,kotlin,role="secondary"]
- ----
- @Bean
- fun clientRegistrations(): ReactiveClientRegistrationRepository {
- val clientRegistration: ClientRegistration = ClientRegistrations
- .fromIssuerLocation("https://idp.example.com/auth/realms/demo")
- .clientId("spring-security")
- .clientSecret("6cea952f-10d0-4d00-ac79-cc865820dc2c")
- .build()
- return InMemoryReactiveClientRegistrationRepository(clientRegistration)
- }
- @Bean
- fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
- return http {
- oauth2Login { }
- }
- }
- ----
- ====
- Additional configuration options can be seen below:
- .Advanced OAuth2 Login
- ====
- .Java
- [source,java,role="primary"]
- ----
- @Bean
- SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
- http
- // ...
- .oauth2Login(oauth2 -> oauth2
- .authenticationConverter(converter)
- .authenticationManager(manager)
- .authorizedClientRepository(authorizedClients)
- .clientRegistrationRepository(clientRegistrations)
- );
- return http.build();
- }
- ----
- .Kotlin
- [source,kotlin,role="secondary"]
- ----
- @Bean
- fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
- return http {
- oauth2Login {
- authenticationConverter = converter
- authenticationManager = manager
- authorizedClientRepository = authorizedClients
- clientRegistrationRepository = clientRegistration
- }
- }
- }
- ----
- ====
- You may register a `GrantedAuthoritiesMapper` `@Bean` to have it automatically applied to the default configuration, as shown in the following example:
- .GrantedAuthoritiesMapper Bean
- ====
- .Java
- [source,java,role="primary"]
- ----
- @Bean
- public GrantedAuthoritiesMapper userAuthoritiesMapper() {
- ...
- }
- @Bean
- SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
- http
- // ...
- .oauth2Login(withDefaults());
- return http.build();
- }
- ----
- .Kotlin
- [source,kotlin,role="secondary"]
- ----
- @Bean
- fun userAuthoritiesMapper(): GrantedAuthoritiesMapper {
- // ...
- }
- @Bean
- fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
- return http {
- oauth2Login { }
- }
- }
- ----
- ====
|