package org.cloudfoundry.identity.uaa.provider.saml; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.client.utils.URIBuilder; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.savedrequest.DefaultSavedRequest; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.net.URI; import static org.cloudfoundry.identity.uaa.web.UaaSavedRequestAwareAuthenticationSuccessHandler.SAVED_REQUEST_SESSION_ATTRIBUTE; /** * This class is used to provide OAuth error redirects when SAML login fails * with LoginSAMLException. Currently, the only scenario for this is when a * shadow account does not exist for the user and the IdP configuration does not * allow automatic creation of the shadow account. * */ public class LoginSAMLAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { private static final Log LOG = LogFactory.getLog(LoginSAMLAuthenticationFailureHandler.class); @Override public void onAuthenticationFailure(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException exception) throws IOException, ServletException { String redirectTo = null; if (exception instanceof LoginSAMLException) { HttpSession session = request.getSession(); if (session != null) { DefaultSavedRequest savedRequest = (DefaultSavedRequest) session.getAttribute(SAVED_REQUEST_SESSION_ATTRIBUTE); if (savedRequest != null) { String[] redirectURI = savedRequest.getParameterMap().get("redirect_uri"); if (redirectURI != null && redirectURI.length > 0) { URI uri = URI.create(redirectURI[0]); URIBuilder uriBuilder = new URIBuilder(uri); uriBuilder.addParameter("error", "access_denied"); uriBuilder.addParameter("error_description", exception.getMessage()); redirectTo = uriBuilder.toString(); if (LOG.isDebugEnabled()) { LOG.debug("Error redirect to: " + redirectTo); } getRedirectStrategy().sendRedirect(request, response, redirectTo); } } } } if (redirectTo == null) { Throwable cause = exception.getCause(); if (cause != null) { AuthenticationException e = new AuthenticationServiceException(cause.getMessage(), cause.getCause()); logger.debug(cause); super.onAuthenticationFailure(request, response, e); } else { logger.debug(exception); super.onAuthenticationFailure(request, response, exception); } } } }