package org.apereo.cas.support.saml.web.idp.profile.sso; import net.shibboleth.utilities.java.support.xml.ParserPool; import org.apache.commons.lang3.tuple.Pair; import org.apereo.cas.authentication.AuthenticationSystemSupport; import org.apereo.cas.authentication.principal.ServiceFactory; import org.apereo.cas.authentication.principal.WebApplicationService; import org.apereo.cas.services.ServicesManager; import org.apereo.cas.support.saml.OpenSamlConfigBean; import org.apereo.cas.support.saml.SamlIdPConstants; import org.apereo.cas.support.saml.services.idp.metadata.cache.SamlRegisteredServiceCachingMetadataResolver; import org.apereo.cas.support.saml.web.idp.profile.AbstractSamlProfileHandlerController; import org.apereo.cas.support.saml.web.idp.profile.builders.SamlProfileObjectBuilder; import org.apereo.cas.support.saml.web.idp.profile.builders.enc.BaseSamlObjectSigner; import org.apereo.cas.support.saml.web.idp.profile.builders.enc.SamlObjectSignatureValidator; import org.opensaml.messaging.context.MessageContext; import org.opensaml.messaging.decoder.servlet.BaseHttpServletRequestXMLMessageDecoder; import org.opensaml.saml.common.SignableSAMLObject; import org.opensaml.saml.saml2.binding.decoding.impl.HTTPPostDecoder; import org.opensaml.saml.saml2.binding.decoding.impl.HTTPRedirectDeflateDecoder; import org.opensaml.saml.saml2.core.AuthnRequest; import org.opensaml.saml.saml2.core.Response; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Set; /** * The {@link SSOPostProfileHandlerController} is responsible for * handling profile requests for SAML2 Web SSO. * * @author Misagh Moayyed * @since 5.0.0 */ public class SSOPostProfileHandlerController extends AbstractSamlProfileHandlerController { /** * Instantiates a new idp-sso saml profile handler controller. * * @param samlObjectSigner the saml object signer * @param parserPool the parser pool * @param authenticationSystemSupport the authentication system support * @param servicesManager the services manager * @param webApplicationServiceFactory the web application service factory * @param samlRegisteredServiceCachingMetadataResolver the saml registered service caching metadata resolver * @param configBean the config bean * @param responseBuilder the response builder * @param authenticationContextClassMappings the authentication context class mappings * @param serverPrefix the server prefix * @param serverName the server name * @param authenticationContextRequestParameter the authentication context request parameter * @param loginUrl the login url * @param logoutUrl the logout url * @param forceSignedLogoutRequests the force signed logout requests * @param singleLogoutCallbacksDisabled the single logout callbacks disabled * @param samlObjectSignatureValidator the saml object signature validator */ public SSOPostProfileHandlerController(final BaseSamlObjectSigner samlObjectSigner, final ParserPool parserPool, final AuthenticationSystemSupport authenticationSystemSupport, final ServicesManager servicesManager, final ServiceFactory<WebApplicationService> webApplicationServiceFactory, final SamlRegisteredServiceCachingMetadataResolver samlRegisteredServiceCachingMetadataResolver, final OpenSamlConfigBean configBean, final SamlProfileObjectBuilder<Response> responseBuilder, final Set<String> authenticationContextClassMappings, final String serverPrefix, final String serverName, final String authenticationContextRequestParameter, final String loginUrl, final String logoutUrl, final boolean forceSignedLogoutRequests, final boolean singleLogoutCallbacksDisabled, final SamlObjectSignatureValidator samlObjectSignatureValidator) { super(samlObjectSigner, parserPool, authenticationSystemSupport, servicesManager, webApplicationServiceFactory, samlRegisteredServiceCachingMetadataResolver, configBean, responseBuilder, authenticationContextClassMappings, serverPrefix, serverName, authenticationContextRequestParameter, loginUrl, logoutUrl, forceSignedLogoutRequests, singleLogoutCallbacksDisabled, samlObjectSignatureValidator); } /** * Handle SSO POST profile request. * * @param response the response * @param request the request * @throws Exception the exception */ @GetMapping(path = SamlIdPConstants.ENDPOINT_SAML2_SSO_PROFILE_REDIRECT) protected void handleSaml2ProfileSsoRedirectRequest(final HttpServletResponse response, final HttpServletRequest request) throws Exception { handleSsoPostProfileRequest(response, request, new HTTPRedirectDeflateDecoder()); } /** * Handle SSO POST profile request. * * @param response the response * @param request the request * @throws Exception the exception */ @PostMapping(path = SamlIdPConstants.ENDPOINT_SAML2_SSO_PROFILE_POST) protected void handleSaml2ProfileSsoPostRequest(final HttpServletResponse response, final HttpServletRequest request) throws Exception { handleSsoPostProfileRequest(response, request, new HTTPPostDecoder()); } /** * Handle profile request. * * @param response the response * @param request the request * @param decoder the decoder * @throws Exception the exception */ protected void handleSsoPostProfileRequest(final HttpServletResponse response, final HttpServletRequest request, final BaseHttpServletRequestXMLMessageDecoder decoder) throws Exception { final Pair<? extends SignableSAMLObject, MessageContext> authnRequest = retrieveAuthnRequest(request, decoder); initiateAuthenticationRequest(authnRequest, response, request); } /** * Retrieve authn request. * * @param request the request * @param decoder the decoder * @return the authn request */ protected Pair<? extends SignableSAMLObject, MessageContext> retrieveAuthnRequest(final HttpServletRequest request, final BaseHttpServletRequestXMLMessageDecoder decoder) { return decodeSamlContextFromHttpRequest(request, decoder, AuthnRequest.class); } }