From d946cfb4a75fd85107300917006e9dd4b8d5db83 Mon Sep 17 00:00:00 2001 From: Justin Richer Date: Mon, 20 Jan 2014 17:07:35 -0500 Subject: [PATCH] added support for target uri parameter in third party issuer (or other custom issuer that sets the right flag on return), closes #539 --- .../client/OIDCAuthenticationFilter.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationFilter.java b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationFilter.java index 0c19467d7..340192951 100644 --- a/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationFilter.java +++ b/openid-connect-client/src/main/java/org/mitre/openid/connect/client/OIDCAuthenticationFilter.java @@ -26,6 +26,7 @@ import java.text.ParseException; import java.util.Date; import java.util.Map; +import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -52,6 +53,7 @@ import org.springframework.security.authentication.AuthenticationServiceExceptio import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.HttpClientErrorException; @@ -77,6 +79,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi protected final static String STATE_SESSION_VARIABLE = "state"; protected final static String NONCE_SESSION_VARIABLE = "nonce"; protected final static String ISSUER_SESSION_VARIABLE = "issuer"; + protected static final String TARGET_SESSION_VARIABLE = "target"; protected final static int HTTP_SOCKET_TIMEOUT = 30000; protected final static String FILTER_PROCESSES_URL = "/openid_connect_login"; @@ -94,6 +97,9 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi private AuthRequestOptionsService authOptions = new StaticAuthRequestOptionsService(); // initialize with an empty set of options private AuthRequestUrlBuilder authRequestBuilder; + // private helper to handle target link URLs + private TargetLinkURIAuthenticationSuccessHandler targetSuccessHandler = new TargetLinkURIAuthenticationSuccessHandler(); + protected int httpSocketTimeout = HTTP_SOCKET_TIMEOUT; /** @@ -101,6 +107,8 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi */ protected OIDCAuthenticationFilter() { super(FILTER_PROCESSES_URL); + targetSuccessHandler.passthrough = super.getSuccessHandler(); + super.setAuthenticationSuccessHandler(targetSuccessHandler); } @Override @@ -169,6 +177,11 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi } else { String issuer = issResp.getIssuer(); + if (!Strings.isNullOrEmpty(issResp.getTargetLinkUri())) { + // there's a target URL in the response, we should save this so we can forward to it later + session.setAttribute(TARGET_SESSION_VARIABLE, issResp.getTargetLinkUri()); + } + if (Strings.isNullOrEmpty(issuer)) { logger.error("No issuer found: " + issuer); throw new AuthenticationServiceException("No issuer found: " + issuer); @@ -525,6 +538,47 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi } + @Override + public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) { + targetSuccessHandler.passthrough = successHandler; + super.setAuthenticationSuccessHandler(targetSuccessHandler); + } + + + + + /** + * Handle a successful authentication event. If the issuer service sets + * a target URL, we'll go to that. Otherwise we'll let the superclass handle + * it for us with the configured behavior. + */ + protected class TargetLinkURIAuthenticationSuccessHandler implements AuthenticationSuccessHandler { + + private AuthenticationSuccessHandler passthrough; + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, + HttpServletResponse response, Authentication authentication) + throws IOException, ServletException { + + HttpSession session = request.getSession(); + + // check to see if we've got a target + String target = getStoredSessionString(session, TARGET_SESSION_VARIABLE); + + if (!Strings.isNullOrEmpty(target)) { + // TODO (#547): should we (can we?) check to see if this URL is part of our app's namespace? + session.removeAttribute(TARGET_SESSION_VARIABLE); + response.sendRedirect(target); + } else { + // if the target was blank, use the default behavior here + passthrough.onAuthenticationSuccess(request, response, authentication); + } + + } + + } + // // Getters and setters for configuration variables