Add How-to: Authenticate using Social Login
Closes gh-538
This commit is contained in:
@@ -7,7 +7,9 @@ asciidoctor {
|
|||||||
"spring-authorization-server-version": project.version,
|
"spring-authorization-server-version": project.version,
|
||||||
"spring-security-reference-base-url": "https://docs.spring.io/spring-security/reference",
|
"spring-security-reference-base-url": "https://docs.spring.io/spring-security/reference",
|
||||||
"spring-security-api-base-url": "https://docs.spring.io/spring-security/site/docs/current/api",
|
"spring-security-api-base-url": "https://docs.spring.io/spring-security/site/docs/current/api",
|
||||||
|
"spring-boot-reference-base-url": "https://docs.spring.io/spring-boot/docs/current/reference/html",
|
||||||
"examples-dir": "examples",
|
"examples-dir": "examples",
|
||||||
|
"samples-dir": "$rootDir/samples",
|
||||||
"docs-java": "$sourceDir/examples/src/main/java",
|
"docs-java": "$sourceDir/examples/src/main/java",
|
||||||
"chomp": "default headers packages",
|
"chomp": "default headers packages",
|
||||||
"toc": "left",
|
"toc": "left",
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020-2022 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package sample.socialLogin;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||||
|
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
|
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SecurityConfig {
|
||||||
|
|
||||||
|
@Bean // <1>
|
||||||
|
@Order(1)
|
||||||
|
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
|
||||||
|
throws Exception {
|
||||||
|
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
|
||||||
|
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
|
||||||
|
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
// Redirect to the OAuth 2.0 Login endpoint when not authenticated
|
||||||
|
// from the authorization endpoint
|
||||||
|
.exceptionHandling((exceptions) -> exceptions
|
||||||
|
.defaultAuthenticationEntryPointFor( // <2>
|
||||||
|
new LoginUrlAuthenticationEntryPoint("/oauth2/authorization/my-client"),
|
||||||
|
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// Accept access tokens for User Info and/or Client Registration
|
||||||
|
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean // <3>
|
||||||
|
@Order(2)
|
||||||
|
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
|
||||||
|
throws Exception {
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
.authorizeHttpRequests((authorize) -> authorize
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
)
|
||||||
|
// OAuth2 Login handles the redirect to the OAuth 2.0 Login endpoint
|
||||||
|
// from the authorization server filter chain
|
||||||
|
.oauth2Login(Customizer.withDefaults()); // <4>
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
okta:
|
||||||
|
base-url: ${OKTA_BASE_URL}
|
||||||
|
|
||||||
|
spring:
|
||||||
|
security:
|
||||||
|
oauth2:
|
||||||
|
client:
|
||||||
|
registration:
|
||||||
|
my-client:
|
||||||
|
provider: okta
|
||||||
|
client-id: ${OKTA_CLIENT_ID}
|
||||||
|
client-secret: ${OKTA_CLIENT_SECRET}
|
||||||
|
scope:
|
||||||
|
- openid
|
||||||
|
- profile
|
||||||
|
- email
|
||||||
|
provider:
|
||||||
|
okta:
|
||||||
|
authorization-uri: ${okta.base-url}/oauth2/v1/authorize
|
||||||
|
token-uri: ${okta.base-url}/oauth2/v1/token
|
||||||
|
user-info-uri: ${okta.base-url}/oauth2/v1/userinfo
|
||||||
|
jwk-set-uri: ${okta.base-url}/oauth2/v1/keys
|
||||||
|
user-name-attribute: sub
|
||||||
217
docs/src/docs/asciidoc/guides/how-to-social-login.adoc
Normal file
217
docs/src/docs/asciidoc/guides/how-to-social-login.adoc
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
[[how-to-social-login]]
|
||||||
|
= How-to: Authenticate using Social Login
|
||||||
|
:index-link: ../how-to.html
|
||||||
|
:docs-dir: ..
|
||||||
|
:examples-dir: {docs-dir}/examples
|
||||||
|
:samples-dir: {docs-dir}/../../../../samples
|
||||||
|
:github-ref: main
|
||||||
|
:github-base-url: https://github.com/spring-projects/spring-authorization-server/blob/{github-ref}
|
||||||
|
|
||||||
|
This guide shows how to configure xref:{docs-dir}/index.adoc#top[Spring Authorization Server] with a social login provider (such as Google, GitHub, etc.) for {spring-security-reference-base-url}/servlet/authentication/index.html[authentication].
|
||||||
|
The purpose of this guide is to demonstrate how to replace {spring-security-reference-base-url}/servlet/authentication/passwords/form.html[Form Login] with {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login].
|
||||||
|
|
||||||
|
NOTE: Spring Authorization Server is built on {spring-security-reference-base-url}/index.html[Spring Security] and we will be using Spring Security concepts throughout this guide.
|
||||||
|
|
||||||
|
* <<register-social-login-provider>>
|
||||||
|
* <<configure-oauth2-login>>
|
||||||
|
* <<advanced-use-cases>>
|
||||||
|
|
||||||
|
[[register-social-login-provider]]
|
||||||
|
== Register with Social Login Provider
|
||||||
|
|
||||||
|
To get started, you will need to set up an application with your chosen social login provider.
|
||||||
|
Common providers include:
|
||||||
|
|
||||||
|
* https://developers.google.com/identity/openid-connect/openid-connect#appsetup[Google]
|
||||||
|
* https://github.com/settings/developers[GitHub]
|
||||||
|
* https://developers.facebook.com/apps[Facebook]
|
||||||
|
* https://www.okta.com/developer/signup[Okta]
|
||||||
|
|
||||||
|
Follow the steps for your provider until you are asked to specify a Redirect URI.
|
||||||
|
To set up a Redirect URI, choose a `registrationId` (such as `google`, `my-client` or any other unique identifier you wish) which you will use to configure both Spring Security **and** your provider.
|
||||||
|
|
||||||
|
NOTE: The `registrationId` is a unique identifier for the `ClientRegistration` in Spring Security. The default Redirect URI template is `\{baseUrl\}/login/oauth2/code/\{registrationId\}`. See {spring-security-reference-base-url}/servlet/oauth2/login/core.html#oauth2login-sample-redirect-uri[Setting the Redirect URI] in the Spring Security reference for more information.
|
||||||
|
|
||||||
|
TIP: For example, testing locally on port `9000` with a `registrationId` of `google`, your Redirect URI would be `http://localhost:9000/login/oauth2/code/google`. Enter this value as the Redirect URI when setting up the application with your provider.
|
||||||
|
|
||||||
|
Once you've completed the set-up process with your social login provider, you should have obtained credentials (a Client ID and Client Secret).
|
||||||
|
In addition, you will need to reference the provider's documentation and take note of the following values:
|
||||||
|
|
||||||
|
* **Authorization URI**: The endpoint that is used to initiate the `authorization_code` flow at the provider.
|
||||||
|
* **Token URI**: The endpoint that is used to exchange an `authorization_code` for an `access_token` and optionally an `id_token`.
|
||||||
|
* **JWK Set URI**: The endpoint that is used to obtain keys for verifying the signature of a JWT, which is required when an `id_token` is available.
|
||||||
|
* **User Info URI**: The endpoint that is used to obtain user information, which is required when an `id_token` is not available.
|
||||||
|
* **User Name Attribute**: The claim in either the `id_token` or the User Info Response containing the username of the user.
|
||||||
|
|
||||||
|
[[configure-oauth2-login]]
|
||||||
|
== Configure OAuth 2.0 Login
|
||||||
|
|
||||||
|
Once you've <<register-social-login-provider,registered>> with a social login provider, you can proceed to configuring Spring Security for {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login].
|
||||||
|
|
||||||
|
* <<configure-oauth2-login-dependency>>
|
||||||
|
* <<configure-oauth2-login-client-registration>>
|
||||||
|
* <<configure-oauth2-login-authentication>>
|
||||||
|
|
||||||
|
[[configure-oauth2-login-dependency]]
|
||||||
|
=== Add OAuth2 Client Dependency
|
||||||
|
|
||||||
|
First, add the following dependency:
|
||||||
|
|
||||||
|
[[configure-oauth2-login-maven-dependency]]
|
||||||
|
.Maven
|
||||||
|
[source,xml,role="primary",subs="attributes,verbatim"]
|
||||||
|
----
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
----
|
||||||
|
|
||||||
|
[[configure-oauth2-login-gradle-dependency]]
|
||||||
|
.Gradle
|
||||||
|
[source,gradle,role="secondary",subs="attributes,verbatim"]
|
||||||
|
----
|
||||||
|
implementation "org.springframework.boot:spring-boot-starter-oauth2-client"
|
||||||
|
----
|
||||||
|
|
||||||
|
[[configure-oauth2-login-client-registration]]
|
||||||
|
=== Register a Client
|
||||||
|
|
||||||
|
Next, configure the `ClientRegistration` with the values obtained <<register-social-login-provider,earlier>>.
|
||||||
|
Using Okta as an example, configure the following properties:
|
||||||
|
|
||||||
|
[[configure-oauth2-login-okta-example]]
|
||||||
|
.application.yml
|
||||||
|
[source,yaml]
|
||||||
|
----
|
||||||
|
include::{examples-dir}/src/main/java/sample/socialLogin/application.yml[]
|
||||||
|
----
|
||||||
|
|
||||||
|
NOTE: The `registrationId` in the above example is `my-client`.
|
||||||
|
|
||||||
|
TIP: The above example demonstrates the *recommended* way to set the Provider URL, Client ID and Client Secret using environment variables (`OKTA_BASE_URL`, `OKTA_CLIENT_ID` and `OKTA_CLIENT_SECRET`). See {spring-boot-reference-base-url}/features.html#features.external-config[Externalized Configuration] in the Spring Boot reference for more information.
|
||||||
|
|
||||||
|
This simple example demonstrates a typical configuration, but some providers will require additional configuration.
|
||||||
|
For more information about configuring the `ClientRegistration`, see {spring-security-reference-base-url}/servlet/oauth2/login/core.html#oauth2login-boot-property-mappings[Spring Boot Property Mappings] in the Spring Security reference.
|
||||||
|
|
||||||
|
[[configure-oauth2-login-authentication]]
|
||||||
|
=== Configure Authentication
|
||||||
|
|
||||||
|
Finally, to configure Spring Authorization Server to use a social login provider for authentication, you can use `oauth2Login()` instead of `formLogin()`.
|
||||||
|
You can also automatically redirect an unauthenticated user to the provider by configuring `exceptionHandling()` with an `AuthenticationEntryPoint`.
|
||||||
|
|
||||||
|
Continuing our <<configure-oauth2-login-okta-example,earlier example>>, configure Spring Security using a `@Configuration` as in the following example:
|
||||||
|
|
||||||
|
.Configure OAuth 2.0 Login
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
include::{examples-dir}/src/main/java/sample/socialLogin/SecurityConfig.java[]
|
||||||
|
----
|
||||||
|
|
||||||
|
<1> A Spring Security filter chain for the xref:protocol-endpoints.adoc[Protocol Endpoints].
|
||||||
|
<2> Configure an `AuthenticationEntryPoint` for redirecting to the {spring-security-reference-base-url}/servlet/oauth2/login/advanced.html#oauth2login-advanced-login-page[OAuth 2.0 Login endpoint].
|
||||||
|
<3> A Spring Security filter chain for https://docs.spring.io/spring-security/reference/servlet/authentication/index.html[authentication].
|
||||||
|
<4> Configure {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login] for authentication.
|
||||||
|
|
||||||
|
If you configured a `UserDetailsService` when xref:{docs-dir}/getting-started.adoc#developing-your-first-application[getting started], you can remove it now.
|
||||||
|
|
||||||
|
[[advanced-use-cases]]
|
||||||
|
== Advanced Use Cases
|
||||||
|
|
||||||
|
The https://github.com/spring-projects/spring-authorization-server/tree/{github-ref}/samples#demo-sample[demo authorization server sample^] demonstrates advanced configuration options for federating identity providers.
|
||||||
|
Select from the following use cases to see an example of each:
|
||||||
|
|
||||||
|
* I want to <<advanced-use-cases-automatically-redirect>>
|
||||||
|
* I want to <<advanced-use-cases-capture-users>>
|
||||||
|
* I want to <<advanced-use-cases-map-claims>>
|
||||||
|
* I want to <<advanced-use-cases-configurer>>
|
||||||
|
|
||||||
|
[[advanced-use-cases-automatically-redirect]]
|
||||||
|
=== Automatically Redirect to a Provider
|
||||||
|
|
||||||
|
The following example `AuthenticationEntryPoint` uses a query parameter as a hint from the client to indicate which provider to automatically redirect to for authentication.
|
||||||
|
For example, assuming Google is configured as a social login provider with a `registrationId` of `google`, a request to `/oauth2/authorize?idp=google&...` will redirect an unauthenticated user to `/oauth2/authorization/google` which will initiate logging in with Google:
|
||||||
|
|
||||||
|
.`FederatedIdentityAuthenticationEntryPoint`
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationEntryPoint.java[]
|
||||||
|
----
|
||||||
|
|
||||||
|
[[advanced-use-cases-capture-users]]
|
||||||
|
=== Capture Users in a Database
|
||||||
|
|
||||||
|
The following example `AuthenticationSuccessHandler` uses a custom component to capture users in a local database when they first log in:
|
||||||
|
|
||||||
|
.`FederatedIdentityAuthenticationSuccessHandler`
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationSuccessHandler.java[]
|
||||||
|
----
|
||||||
|
|
||||||
|
Using the `AuthenticationSuccessHandler` above, you can plug in your own `Consumer<OAuth2User>` that can capture users in a database or other data store for concepts like Federated Account Linking or JIT Account Provisioning.
|
||||||
|
Here is an example that simply stores users in-memory:
|
||||||
|
|
||||||
|
.`UserRepositoryOAuth2UserHandler`
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/UserRepositoryOAuth2UserHandler.java[]
|
||||||
|
----
|
||||||
|
|
||||||
|
[[advanced-use-cases-map-claims]]
|
||||||
|
=== Map Claims to an ID Token
|
||||||
|
|
||||||
|
The following example `OAuth2TokenCustomizer` maps a user's claims from an authentication provider to the `id_token` produced by Spring Authorization Server:
|
||||||
|
|
||||||
|
.`FederatedIdentityIdTokenCustomizer`
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityIdTokenCustomizer.java[]
|
||||||
|
----
|
||||||
|
|
||||||
|
You can configure Spring Authorization Server to use this customizer by publishing it as a `@Bean` as in the following example:
|
||||||
|
|
||||||
|
.Configure `FederatedIdentityIdTokenCustomizer`
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
public OAuth2TokenCustomizer<JwtEncodingContext> idTokenCustomizer() {
|
||||||
|
return new FederatedIdentityIdTokenCustomizer();
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
[[advanced-use-cases-configurer]]
|
||||||
|
=== Create My Own Configurer
|
||||||
|
|
||||||
|
The following example `SecurityConfigurer` combines configuration for all of the above examples into a single reusable component:
|
||||||
|
|
||||||
|
.`FederatedIdentityConfigurer`
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityConfigurer.java[]
|
||||||
|
----
|
||||||
|
|
||||||
|
The configurer can be applied using the Spring Security DSL as in the following example:
|
||||||
|
|
||||||
|
.Apply Configurer
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
http.apply(new FederatedIdentityConfigurer());
|
||||||
|
----
|
||||||
|
|
||||||
|
The configurer also has its own DSL to customize the defaults.
|
||||||
|
Here's a full example:
|
||||||
|
|
||||||
|
.Customize using Configurer
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
http.apply(new FederatedIdentityConfigurer())
|
||||||
|
.loginPageUrl("/social/login")
|
||||||
|
.authorizationRequestUri("/social/login/{registrationId}")
|
||||||
|
.oauth2UserHandler((oauth2User) -> {
|
||||||
|
// TODO: Handle login of an OAuth2 user...
|
||||||
|
})
|
||||||
|
.oidcUserHandler((oidcUser) -> {
|
||||||
|
// TODO: Handle login of an OIDC user...
|
||||||
|
});
|
||||||
|
----
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
[[how-to-overview]]
|
[[how-to-overview]]
|
||||||
== List of Guides
|
== List of Guides
|
||||||
|
|
||||||
|
* xref:guides/how-to-social-login.adoc[Authenticate using Social Login]
|
||||||
* xref:guides/how-to-userinfo.adoc[Customize the OpenID Connect 1.0 UserInfo response]
|
* xref:guides/how-to-userinfo.adoc[Customize the OpenID Connect 1.0 UserInfo response]
|
||||||
* xref:guides/how-to-jpa.adoc[Implement core services with JPA]
|
* xref:guides/how-to-jpa.adoc[Implement core services with JPA]
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package sample.federation;
|
package sample.federation;
|
||||||
|
|
||||||
|
// tag::imports[]
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
@@ -31,6 +32,7 @@ import org.springframework.security.web.DefaultRedirectStrategy;
|
|||||||
import org.springframework.security.web.RedirectStrategy;
|
import org.springframework.security.web.RedirectStrategy;
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
// end::imports[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link AuthenticationEntryPoint} for initiating the login flow to an
|
* An {@link AuthenticationEntryPoint} for initiating the login flow to an
|
||||||
@@ -40,6 +42,7 @@ import org.springframework.web.util.UriComponentsBuilder;
|
|||||||
* @author Steve Riesenberg
|
* @author Steve Riesenberg
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
// tag::class[]
|
||||||
public final class FederatedIdentityAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
public final class FederatedIdentityAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
|
|
||||||
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
||||||
@@ -80,3 +83,4 @@ public final class FederatedIdentityAuthenticationEntryPoint implements Authenti
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// end::class[]
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package sample.federation;
|
package sample.federation;
|
||||||
|
|
||||||
|
// tag::imports[]
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@@ -28,6 +29,7 @@ import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
|||||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||||
|
// end::imports[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link AuthenticationSuccessHandler} for capturing the {@link OidcUser} or
|
* An {@link AuthenticationSuccessHandler} for capturing the {@link OidcUser} or
|
||||||
@@ -36,6 +38,7 @@ import org.springframework.security.web.authentication.SavedRequestAwareAuthenti
|
|||||||
* @author Steve Riesenberg
|
* @author Steve Riesenberg
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
// tag::class[]
|
||||||
public final class FederatedIdentityAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
|
public final class FederatedIdentityAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
|
||||||
|
|
||||||
private final AuthenticationSuccessHandler delegate = new SavedRequestAwareAuthenticationSuccessHandler();
|
private final AuthenticationSuccessHandler delegate = new SavedRequestAwareAuthenticationSuccessHandler();
|
||||||
@@ -66,3 +69,4 @@ public final class FederatedIdentityAuthenticationSuccessHandler implements Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// end::class[]
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package sample.federation;
|
package sample.federation;
|
||||||
|
|
||||||
|
// tag::imports[]
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
@@ -24,6 +25,7 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
|
|||||||
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
||||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
// end::imports[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A configurer for setting up Federated Identity Management.
|
* A configurer for setting up Federated Identity Management.
|
||||||
@@ -31,6 +33,7 @@ import org.springframework.util.Assert;
|
|||||||
* @author Steve Riesenberg
|
* @author Steve Riesenberg
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
// tag::class[]
|
||||||
public final class FederatedIdentityConfigurer extends AbstractHttpConfigurer<FederatedIdentityConfigurer, HttpSecurity> {
|
public final class FederatedIdentityConfigurer extends AbstractHttpConfigurer<FederatedIdentityConfigurer, HttpSecurity> {
|
||||||
|
|
||||||
private String loginPageUrl = "/login";
|
private String loginPageUrl = "/login";
|
||||||
@@ -123,3 +126,4 @@ public final class FederatedIdentityConfigurer extends AbstractHttpConfigurer<Fe
|
|||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// end::class[]
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package sample.federation;
|
package sample.federation;
|
||||||
|
|
||||||
|
// tag::imports[]
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -30,6 +31,7 @@ import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
|||||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||||
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
|
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
|
||||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
|
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
|
||||||
|
// end::imports[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link OAuth2TokenCustomizer} to map claims from a federated identity to
|
* An {@link OAuth2TokenCustomizer} to map claims from a federated identity to
|
||||||
@@ -38,6 +40,7 @@ import org.springframework.security.oauth2.server.authorization.token.OAuth2Toke
|
|||||||
* @author Steve Riesenberg
|
* @author Steve Riesenberg
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
// tag::class[]
|
||||||
public final class FederatedIdentityIdTokenCustomizer implements OAuth2TokenCustomizer<JwtEncodingContext> {
|
public final class FederatedIdentityIdTokenCustomizer implements OAuth2TokenCustomizer<JwtEncodingContext> {
|
||||||
|
|
||||||
private static final Set<String> ID_TOKEN_CLAIMS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
private static final Set<String> ID_TOKEN_CLAIMS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||||
@@ -89,3 +92,4 @@ public final class FederatedIdentityIdTokenCustomizer implements OAuth2TokenCust
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// end::class[]
|
||||||
|
|||||||
@@ -15,11 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package sample.federation;
|
package sample.federation;
|
||||||
|
|
||||||
|
// tag::imports[]
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||||
|
// end::imports[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example {@link Consumer} to perform JIT provisioning of an {@link OAuth2User}.
|
* Example {@link Consumer} to perform JIT provisioning of an {@link OAuth2User}.
|
||||||
@@ -27,6 +29,7 @@ import org.springframework.security.oauth2.core.user.OAuth2User;
|
|||||||
* @author Steve Riesenberg
|
* @author Steve Riesenberg
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
// tag::class[]
|
||||||
public final class UserRepositoryOAuth2UserHandler implements Consumer<OAuth2User> {
|
public final class UserRepositoryOAuth2UserHandler implements Consumer<OAuth2User> {
|
||||||
|
|
||||||
private final UserRepository userRepository = new UserRepository();
|
private final UserRepository userRepository = new UserRepository();
|
||||||
@@ -55,3 +58,4 @@ public final class UserRepositoryOAuth2UserHandler implements Consumer<OAuth2Use
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// end::class[]
|
||||||
|
|||||||
Reference in New Issue
Block a user