Browse Source

Simplified federated login in demo sample

Closes gh-1208
Joe Grandja 2 years ago
parent
commit
5f606ae757

+ 0 - 13
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 <<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[tags=imports;class]
-----
-
 [[advanced-use-cases-capture-users]]
 === Capture Users in a Database
 

+ 4 - 10
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

+ 0 - 86
samples/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationEntryPoint.java

@@ -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[]

+ 4 - 49
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<FederatedIdentityConfigurer, HttpSecurity> {
 
-	private String loginPageUrl = "/login";
-
-	private String authorizationRequestUri;
-
 	private Consumer<OAuth2User> oauth2UserHandler;
 
 	private Consumer<OidcUser> 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<Fe
 	// @formatter:off
 	@Override
 	public void init(HttpSecurity http) throws Exception {
-		ApplicationContext applicationContext = http.getSharedObject(ApplicationContext.class);
-		ClientRegistrationRepository clientRegistrationRepository =
-			applicationContext.getBean(ClientRegistrationRepository.class);
-		FederatedIdentityAuthenticationEntryPoint authenticationEntryPoint =
-			new FederatedIdentityAuthenticationEntryPoint(this.loginPageUrl, clientRegistrationRepository);
-		if (this.authorizationRequestUri != null) {
-			authenticationEntryPoint.setAuthorizationRequestUri(this.authorizationRequestUri);
-		}
-
 		FederatedIdentityAuthenticationSuccessHandler authenticationSuccessHandler =
 			new FederatedIdentityAuthenticationSuccessHandler();
 		if (this.oauth2UserHandler != null) {
@@ -110,18 +74,9 @@ public final class FederatedIdentityConfigurer extends AbstractHttpConfigurer<Fe
 		}
 
 		http
-			.exceptionHandling(exceptionHandling ->
-				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