diff --git a/docs/src/docs/asciidoc/guides/how-to-social-login.adoc b/docs/src/docs/asciidoc/guides/how-to-social-login.adoc index 2b07a48e..53ea5b7f 100644 --- a/docs/src/docs/asciidoc/guides/how-to-social-login.adoc +++ b/docs/src/docs/asciidoc/guides/how-to-social-login.adoc @@ -121,23 +121,10 @@ If you configured a `UserDetailsService` when xref:{docs-dir}/getting-started.ad 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 <> * I want to <> * I want to <> * I want to <> -[[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[tags=imports;class] ----- - [[advanced-use-cases-capture-users]] === Capture Users in a Database diff --git a/samples/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java b/samples/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java index 7b591efb..49899da4 100644 --- a/samples/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java +++ b/samples/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java @@ -15,9 +15,6 @@ */ package sample.config; -import sample.federation.FederatedIdentityConfigurer; -import sample.federation.UserRepositoryOAuth2UserHandler; - import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -31,8 +28,6 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.session.HttpSessionEventPublisher; -import static org.springframework.security.config.Customizer.withDefaults; - /** * @author Joe Grandja * @author Steve Riesenberg @@ -45,17 +40,16 @@ public class DefaultSecurityConfig { // @formatter:off @Bean public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { - FederatedIdentityConfigurer federatedIdentityConfigurer = new FederatedIdentityConfigurer() - .oauth2UserHandler(new UserRepositoryOAuth2UserHandler()); - http .authorizeHttpRequests(authorize -> authorize .requestMatchers("/assets/**", "/webjars/**", "/login").permitAll() .anyRequest().authenticated() ) - .formLogin(withDefaults()) - .apply(federatedIdentityConfigurer); + .formLogin(formLogin -> + formLogin.loginPage("/login") + ); + return http.build(); } // @formatter:on diff --git a/samples/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationEntryPoint.java b/samples/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationEntryPoint.java deleted file mode 100644 index 54efecb3..00000000 --- a/samples/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationEntryPoint.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2020-2023 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.federation; - -// tag::imports[] -import java.io.IOException; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.client.registration.ClientRegistration; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; -import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.DefaultRedirectStrategy; -import org.springframework.security.web.RedirectStrategy; -import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; -import org.springframework.web.util.UriComponentsBuilder; -// end::imports[] - -/** - * An {@link AuthenticationEntryPoint} for initiating the login flow to an - * external provider using the {@code idp} query parameter, which represents the - * {@code registrationId} of the desired {@link ClientRegistration}. - * - * @author Steve Riesenberg - * @since 1.1 - */ -// tag::class[] -public final class FederatedIdentityAuthenticationEntryPoint implements AuthenticationEntryPoint { - - private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); - - private String authorizationRequestUri = OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI - + "/{registrationId}"; - - private final AuthenticationEntryPoint delegate; - - private final ClientRegistrationRepository clientRegistrationRepository; - - public FederatedIdentityAuthenticationEntryPoint(String loginPageUrl, ClientRegistrationRepository clientRegistrationRepository) { - this.delegate = new LoginUrlAuthenticationEntryPoint(loginPageUrl); - this.clientRegistrationRepository = clientRegistrationRepository; - } - - @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException { - String idp = request.getParameter("idp"); - if (idp != null) { - ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(idp); - if (clientRegistration != null) { - String redirectUri = UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request)) - .replaceQuery(null) - .replacePath(this.authorizationRequestUri) - .buildAndExpand(clientRegistration.getRegistrationId()) - .toUriString(); - this.redirectStrategy.sendRedirect(request, response, redirectUri); - return; - } - } - - this.delegate.commence(request, response, authenticationException); - } - - public void setAuthorizationRequestUri(String authorizationRequestUri) { - this.authorizationRequestUri = authorizationRequestUri; - } - -} -// end::class[] diff --git a/samples/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityConfigurer.java b/samples/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityConfigurer.java index 13d4ba02..96079a43 100644 --- a/samples/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityConfigurer.java +++ b/samples/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityConfigurer.java @@ -16,12 +16,11 @@ package sample.federation; // tag::imports[] + import java.util.function.Consumer; -import org.springframework.context.ApplicationContext; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.util.Assert; @@ -36,36 +35,10 @@ import org.springframework.util.Assert; // tag::class[] public final class FederatedIdentityConfigurer extends AbstractHttpConfigurer { - private String loginPageUrl = "/login"; - - private String authorizationRequestUri; - private Consumer oauth2UserHandler; private Consumer oidcUserHandler; - /** - * @param loginPageUrl The URL of the login page, defaults to {@code "/login"} - * @return This configurer for additional configuration - */ - public FederatedIdentityConfigurer loginPageUrl(String loginPageUrl) { - Assert.hasText(loginPageUrl, "loginPageUrl cannot be empty"); - this.loginPageUrl = loginPageUrl; - return this; - } - - /** - * @param authorizationRequestUri The authorization request URI for initiating - * the login flow with an external IDP, defaults to {@code - * "/oauth2/authorization/{registrationId}"} - * @return This configurer for additional configuration - */ - public FederatedIdentityConfigurer authorizationRequestUri(String authorizationRequestUri) { - Assert.hasText(authorizationRequestUri, "authorizationRequestUri cannot be empty"); - this.authorizationRequestUri = authorizationRequestUri; - return this; - } - /** * @param oauth2UserHandler The {@link Consumer} for performing JIT account provisioning * with an OAuth 2.0 IDP @@ -91,15 +64,6 @@ public final class FederatedIdentityConfigurer extends AbstractHttpConfigurer - exceptionHandling.authenticationEntryPoint(authenticationEntryPoint) - ) - .oauth2Login(oauth2Login -> { - oauth2Login.successHandler(authenticationSuccessHandler); - if (this.authorizationRequestUri != null) { - String baseUri = this.authorizationRequestUri.replace("/{registrationId}", ""); - oauth2Login.authorizationEndpoint(authorizationEndpoint -> - authorizationEndpoint.baseUri(baseUri) - ); - } - }); + .oauth2Login(oauth2Login -> + oauth2Login.successHandler(authenticationSuccessHandler) + ); } // @formatter:on