diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java index 3ff1896..3807969 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java @@ -68,6 +68,8 @@ public class AuthenticationFilter extends AbstractCasFilter { private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl(); + private AuthenticationRedirectStrategy authenticationRedirectStrategy = new DefaultAuthenticationRedirectStrategy(); + protected void initInternal(final FilterConfig filterConfig) throws ServletException { if (!isIgnoreInitConfiguration()) { super.initInternal(filterConfig); @@ -81,13 +83,23 @@ public class AuthenticationFilter extends AbstractCasFilter { final String gatewayStorageClass = getPropertyFromInitParams(filterConfig, "gatewayStorageClass", null); if (gatewayStorageClass != null) { - try { - this.gatewayStorage = (GatewayResolver) Class.forName(gatewayStorageClass).newInstance(); - } catch (final Exception e) { - logger.error(e.getMessage(),e); - throw new ServletException(e); - } + this.gatewayStorage = classNameToClass(gatewayStorageClass); } + + final String authenticationRedirectStrategyClass = getPropertyFromInitParams(filterConfig, "authenticationRedirectStrategyClass", null); + + if (authenticationRedirectStrategyClass != null) { + this.authenticationRedirectStrategy = classNameToClass(authenticationRedirectStrategyClass); + } + } + } + + private T classNameToClass(final String className) throws ServletException { + try { + return (T) Class.forName(className).newInstance(); + } catch (final Exception e) { + logger.error(e.getMessage(),e); + throw new ServletException(e); } } @@ -131,8 +143,7 @@ public class AuthenticationFilter extends AbstractCasFilter { final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway); logger.debug("redirecting to \"{}\"", urlToRedirectTo); - - response.sendRedirect(urlToRedirectTo); + this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo); } public final void setRenew(final boolean renew) { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationRedirectStrategy.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationRedirectStrategy.java new file mode 100644 index 0000000..701d852 --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationRedirectStrategy.java @@ -0,0 +1,14 @@ +package org.jasig.cas.client.authentication; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * Created by battags on 6/18/13. + */ +public interface AuthenticationRedirectStrategy { + + void redirect(HttpServletRequest request, HttpServletResponse response, String potentialRedirectUrl) throws IOException; + +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategy.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategy.java new file mode 100644 index 0000000..0d34e4c --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategy.java @@ -0,0 +1,18 @@ +package org.jasig.cas.client.authentication; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * Implementation of the {@link AuthenticationRedirectStrategy} class that preserves the original behavior that existed prior to 3.3.0. + * + * @author Scott Battaglia + * @since 3.3.0 + */ +public final class DefaultAuthenticationRedirectStrategy implements AuthenticationRedirectStrategy { + + public void redirect(final HttpServletRequest request, final HttpServletResponse response, final String potentialRedirectUrl) throws IOException { + response.sendRedirect(potentialRedirectUrl); + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategy.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategy.java new file mode 100644 index 0000000..13ff374 --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategy.java @@ -0,0 +1,34 @@ +package org.jasig.cas.client.authentication; + +import org.jasig.cas.client.util.CommonUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * Implementation of the redirect strategy that can handle a Faces Ajax request in addition to the standard redirect style. + * + * @author Scott Battaglia + * @since 3.3.0 + */ +public final class FacesCompatibleAuthenticationRedirectStrategy implements AuthenticationRedirectStrategy { + + private static final String FACES_PARTIAL_AJAX_PARAMETER = "javax.faces.partial.ajax"; + + public void redirect(final HttpServletRequest request, final HttpServletResponse response, final String potentialRedirectUrl) throws IOException { + + if (CommonUtils.isNotBlank(request.getParameter(FACES_PARTIAL_AJAX_PARAMETER))) { + // this is an ajax request - redirect ajaxly + response.setContentType("text/xml"); + response.setStatus(200); + + final PrintWriter writer = response.getWriter(); + writer.write(""); + writer.write(String.format("", potentialRedirectUrl)); + } else { + response.sendRedirect(potentialRedirectUrl); + } + } +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategyTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategyTests.java new file mode 100644 index 0000000..0b1389e --- /dev/null +++ b/cas-client-core/src/test/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategyTests.java @@ -0,0 +1,28 @@ +package org.jasig.cas.client.authentication; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +public class DefaultAuthenticationRedirectStrategyTests { + + private DefaultAuthenticationRedirectStrategy strategy; + + @Before + public void setUp() throws Exception { + this.strategy = new DefaultAuthenticationRedirectStrategy(); + } + + @Test + public void didWeRedirect() throws Exception { + final String redirectUrl = "http://www.jasig.org"; + final MockHttpServletRequest request = new MockHttpServletRequest(); + final MockHttpServletResponse response = new MockHttpServletResponse(); + + this.strategy.redirect(request, response, redirectUrl); + assertEquals(redirectUrl, response.getRedirectedUrl()); + } +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategyTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategyTests.java new file mode 100644 index 0000000..920cf7f --- /dev/null +++ b/cas-client-core/src/test/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategyTests.java @@ -0,0 +1,39 @@ +package org.jasig.cas.client.authentication; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import static org.junit.Assert.*; + +public class FacesCompatibleAuthenticationRedirectStrategyTests { + + private FacesCompatibleAuthenticationRedirectStrategy strategy; + + @Before + public void setUp() throws Exception { + this.strategy = new FacesCompatibleAuthenticationRedirectStrategy(); + } + + @Test + public void didWeRedirect() throws Exception { + final String redirectUrl = "http://www.jasig.org"; + final MockHttpServletRequest request = new MockHttpServletRequest(); + final MockHttpServletResponse response = new MockHttpServletResponse(); + + this.strategy.redirect(request, response, redirectUrl); + assertEquals(redirectUrl, response.getRedirectedUrl()); + } + + @Test + public void facesPartialResponse() throws Exception { + final String redirectUrl = "http://www.jasig.org"; + final MockHttpServletRequest request = new MockHttpServletRequest(); + final MockHttpServletResponse response = new MockHttpServletResponse(); + request.setParameter("javax.faces.partial.ajax", "true"); + this.strategy.redirect(request, response, redirectUrl); + assertNull(response.getRedirectedUrl()); + assertTrue(response.getContentAsString().contains(redirectUrl)); + } +}