Browse Source

Allow customization of redirect strategy in CasAuthenticationEntrypoint

Closes gh-14881
Marcus Hert Da Coregio 1 year ago
parent
commit
f4712069d7

+ 15 - 3
cas/src/main/java/org/springframework/security/cas/web/CasAuthenticationEntryPoint.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -28,6 +28,7 @@ import org.springframework.security.cas.ServiceProperties;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.AuthenticationEntryPoint;
 import org.springframework.security.web.DefaultRedirectStrategy;
+import org.springframework.security.web.RedirectStrategy;
 import org.springframework.util.Assert;
 
 /**
@@ -61,6 +62,8 @@ public class CasAuthenticationEntryPoint implements AuthenticationEntryPoint, In
 	 */
 	private boolean encodeServiceUrlWithSessionId = true;
 
+	private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+
 	@Override
 	public void afterPropertiesSet() {
 		Assert.hasLength(this.loginUrl, "loginUrl must be specified");
@@ -74,8 +77,7 @@ public class CasAuthenticationEntryPoint implements AuthenticationEntryPoint, In
 		String urlEncodedService = createServiceUrl(servletRequest, response);
 		String redirectUrl = createRedirectUrl(urlEncodedService);
 		preCommence(servletRequest, response);
-		new DefaultRedirectStrategy().sendRedirect(servletRequest, response, redirectUrl);
-		// response.sendRedirect(redirectUrl);
+		this.redirectStrategy.sendRedirect(servletRequest, response, redirectUrl);
 	}
 
 	/**
@@ -149,4 +151,14 @@ public class CasAuthenticationEntryPoint implements AuthenticationEntryPoint, In
 		return this.encodeServiceUrlWithSessionId;
 	}
 
+	/**
+	 * Sets the {@link RedirectStrategy} to use
+	 * @param redirectStrategy the {@link RedirectStrategy} to use
+	 * @since 6.3
+	 */
+	public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
+		Assert.notNull(redirectStrategy, "redirectStrategy cannot be null");
+		this.redirectStrategy = redirectStrategy;
+	}
+
 }

+ 27 - 0
cas/src/test/java/org/springframework/security/cas/web/CasAuthenticationEntryPointTests.java

@@ -16,16 +16,22 @@
 
 package org.springframework.security.cas.web;
 
+import java.io.IOException;
 import java.net.URLEncoder;
 
 import org.junit.jupiter.api.Test;
 
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.cas.ServiceProperties;
+import org.springframework.security.web.RedirectStrategy;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 
 /**
  * Tests {@link CasAuthenticationEntryPoint}.
@@ -95,4 +101,25 @@ public class CasAuthenticationEntryPointTests {
 			.isEqualTo(response.getRedirectedUrl());
 	}
 
+	@Test
+	void setRedirectStrategyThenUses() throws IOException {
+		CasAuthenticationEntryPoint ep = new CasAuthenticationEntryPoint();
+		ServiceProperties sp = new ServiceProperties();
+
+		sp.setService("https://mycompany.com/login/cas");
+		ep.setServiceProperties(sp);
+		ep.setLoginUrl("https://cas/login");
+
+		RedirectStrategy redirectStrategy = mock();
+
+		ep.setRedirectStrategy(redirectStrategy);
+		MockHttpServletRequest req = new MockHttpServletRequest();
+		MockHttpServletResponse res = new MockHttpServletResponse();
+
+		ep.commence(req, res, new BadCredentialsException("bad credentials"));
+
+		verify(redirectStrategy).sendRedirect(eq(req), eq(res),
+				eq("https://cas/login?service=https%3A%2F%2Fmycompany.com%2Flogin%2Fcas"));
+	}
+
 }