Search in sources :

Example 76 with AuthnRequest

use of org.opensaml.saml2.core.AuthnRequest in project cas by apereo.

the class AbstractSamlIdPProfileHandlerController method constructServiceUrl.

/**
 * Construct service url string.
 *
 * @param request  the request
 * @param response the response
 * @param pair     the pair
 * @return the string
 * @throws Exception the exception
 */
protected String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response, final Pair<? extends SignableSAMLObject, MessageContext> pair) throws Exception {
    val authnRequest = (AuthnRequest) pair.getLeft();
    val builder = new URLBuilder(configurationContext.getCallbackService().getId());
    builder.getQueryParams().add(new net.shibboleth.utilities.java.support.collection.Pair<>(SamlProtocolConstants.PARAMETER_ENTITY_ID, SamlIdPUtils.getIssuerFromSamlObject(authnRequest)));
    storeAuthenticationRequest(request, response, pair);
    val url = builder.buildURL();
    LOGGER.trace("Built service callback url [{}]", url);
    return CommonUtils.constructServiceUrl(request, response, url, configurationContext.getCasProperties().getServer().getName(), CasProtocolConstants.PARAMETER_SERVICE, CasProtocolConstants.PARAMETER_TICKET, false);
}
Also used : lombok.val(lombok.val) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) URLBuilder(net.shibboleth.utilities.java.support.net.URLBuilder)

Example 77 with AuthnRequest

use of org.opensaml.saml2.core.AuthnRequest in project cas by apereo.

the class SamlIdPInitiatedProfileHandlerController method handleIdPInitiatedSsoRequest.

/**
 * Handle idp initiated sso requests.
 * The URL of the response location at the SP (called the "Assertion Consumer Service")
 * but can be omitted in favor of the IdP picking the default endpoint location from metadata.
 *
 * @param response the response
 * @param request  the request
 * @return the model and view
 * @throws Exception the exception
 */
@GetMapping(path = SamlIdPConstants.ENDPOINT_SAML2_IDP_INIT_PROFILE_SSO)
protected ModelAndView handleIdPInitiatedSsoRequest(final HttpServletResponse response, final HttpServletRequest request) throws Exception {
    val providerId = request.getParameter(SamlIdPConstants.PROVIDER_ID);
    if (StringUtils.isBlank(providerId)) {
        LOGGER.warn("No providerId parameter given in unsolicited SSO authentication request.");
        throw new MessageDecodingException("Missing providerId");
    }
    val registeredService = verifySamlRegisteredService(providerId);
    val adaptor = getSamlMetadataFacadeFor(registeredService, providerId);
    if (adaptor.isEmpty()) {
        throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, "Cannot find metadata linked to " + providerId);
    }
    var shire = request.getParameter(SamlIdPConstants.SHIRE);
    val facade = adaptor.get();
    if (StringUtils.isBlank(shire)) {
        LOGGER.info("Resolving service provider assertion consumer service URL for [{}] and binding [{}]", providerId, SAMLConstants.SAML2_POST_BINDING_URI);
        val acs = facade.getAssertionConsumerService(SAMLConstants.SAML2_POST_BINDING_URI);
        shire = acs != null ? StringUtils.isBlank(acs.getResponseLocation()) ? acs.getLocation() : acs.getResponseLocation() : null;
    }
    if (StringUtils.isBlank(shire)) {
        LOGGER.warn("Unable to resolve service provider assertion consumer service URL for AuthnRequest construction for entityID: [{}]", providerId);
        throw new MessageDecodingException("Unable to resolve SP ACS URL for AuthnRequest construction");
    }
    val target = request.getParameter(SamlIdPConstants.TARGET);
    val time = request.getParameter(SamlIdPConstants.TIME);
    val builder = (SAMLObjectBuilder) getConfigurationContext().getOpenSamlConfigBean().getBuilderFactory().getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
    val authnRequest = (AuthnRequest) builder.buildObject();
    authnRequest.setAssertionConsumerServiceURL(shire);
    val isBuilder = (SAMLObjectBuilder) getConfigurationContext().getOpenSamlConfigBean().getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
    val issuer = (Issuer) isBuilder.buildObject();
    issuer.setValue(providerId);
    authnRequest.setIssuer(issuer);
    authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
    val pBuilder = (SAMLObjectBuilder) getConfigurationContext().getOpenSamlConfigBean().getBuilderFactory().getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
    val nameIDPolicy = (NameIDPolicy) pBuilder.buildObject();
    nameIDPolicy.setAllowCreate(Boolean.TRUE);
    authnRequest.setNameIDPolicy(nameIDPolicy);
    if (NumberUtils.isCreatable(time)) {
        authnRequest.setIssueInstant(Instant.ofEpochMilli(Long.parseLong(time)));
    } else {
        authnRequest.setIssueInstant(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
    }
    authnRequest.setForceAuthn(Boolean.FALSE);
    if (StringUtils.isNotBlank(target)) {
        request.setAttribute(SamlProtocolConstants.PARAMETER_SAML_RELAY_STATE, target);
    }
    val ctx = new MessageContext();
    if (facade.isAuthnRequestsSigned() || registeredService.isSignUnsolicitedAuthnRequest()) {
        getConfigurationContext().getSamlObjectSigner().encode(authnRequest, registeredService, facade, response, request, SAMLConstants.SAML2_POST_BINDING_URI, authnRequest, ctx);
    }
    ctx.setMessage(authnRequest);
    val bindingContext = ctx.getSubcontext(SAMLBindingContext.class, true);
    Objects.requireNonNull(bindingContext).setHasBindingSignature(false);
    SAMLBindingSupport.setRelayState(ctx, target);
    val pair = Pair.<RequestAbstractType, MessageContext>of(authnRequest, ctx);
    val modelAndView = initiateAuthenticationRequest(pair, response, request);
    if (modelAndView != null) {
        val view = (RedirectView) modelAndView.getView();
        val urlBuilder = new URIBuilder(Objects.requireNonNull(view).getUrl());
        val paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            val parameterName = paramNames.nextElement();
            if (!parameterName.equalsIgnoreCase(SamlIdPConstants.TARGET) && !parameterName.equalsIgnoreCase(SamlIdPConstants.TIME) && !parameterName.equalsIgnoreCase(SamlIdPConstants.SHIRE) && !parameterName.equalsIgnoreCase(SamlIdPConstants.PROVIDER_ID)) {
                urlBuilder.addParameter(parameterName, request.getParameter(parameterName));
            }
        }
        view.setUrl(urlBuilder.build().toString());
    }
    return modelAndView;
}
Also used : lombok.val(lombok.val) MessageDecodingException(org.opensaml.messaging.decoder.MessageDecodingException) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) SAMLObjectBuilder(org.opensaml.saml.common.SAMLObjectBuilder) Issuer(org.opensaml.saml.saml2.core.Issuer) NameIDPolicy(org.opensaml.saml.saml2.core.NameIDPolicy) RequestAbstractType(org.opensaml.saml.saml2.core.RequestAbstractType) RedirectView(org.springframework.web.servlet.view.RedirectView) UnauthorizedServiceException(org.apereo.cas.services.UnauthorizedServiceException) MessageContext(org.opensaml.messaging.context.MessageContext) URIBuilder(org.apache.http.client.utils.URIBuilder) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Example 78 with AuthnRequest

use of org.opensaml.saml2.core.AuthnRequest in project cas by apereo.

the class SamlIdPDelegatedClientAuthenticationRequestCustomizer method isAuthorized.

@Override
public boolean isAuthorized(final JEEContext webContext, final IndirectClient client, final WebApplicationService currentService) {
    val result = SamlIdPUtils.retrieveSamlRequest(webContext, sessionStore, openSamlConfigBean, AuthnRequest.class);
    if (result.isEmpty()) {
        LOGGER.trace("No SAML2 authentication request found in session store");
        return true;
    }
    val authnRequest = (AuthnRequest) result.get().getLeft();
    LOGGER.trace("Retrieved the SAML2 authentication request from [{}]", SamlIdPUtils.getIssuerFromSamlObject(authnRequest));
    val idpList = authnRequest.getScoping() != null ? authnRequest.getScoping().getIDPList() : null;
    val idpEntries = idpList != null && idpList.getIDPEntrys() != null ? idpList.getIDPEntrys() : List.<IDPEntry>of();
    val providerList = idpEntries.stream().map(IDPEntry::getProviderID).collect(Collectors.toList());
    LOGGER.debug("Scoped identity providers are [{}] to examine against client [{}]", providerList, client.getName());
    if (supports(client, webContext)) {
        val saml2Client = (SAML2Client) client;
        LOGGER.debug("Comparing [{}] against scoped identity providers [{}]", saml2Client.getIdentityProviderResolvedEntityId(), providerList);
        return providerList.isEmpty() || providerList.contains(saml2Client.getIdentityProviderResolvedEntityId());
    }
    return true;
}
Also used : lombok.val(lombok.val) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) SAML2Client(org.pac4j.saml.client.SAML2Client)

Example 79 with AuthnRequest

use of org.opensaml.saml2.core.AuthnRequest in project cas by apereo.

the class SamlIdPUtils method determineEndpointForRequest.

private static AssertionConsumerService determineEndpointForRequest(final RequestAbstractType authnRequest, final SamlRegisteredServiceServiceProviderMetadataFacade adaptor, final String binding, final AssertionConsumerService acsFromRequest, final AssertionConsumerService acsFromMetadata, final MessageContext authenticationContext) {
    LOGGER.trace("ACS from authentication request is [{}], ACS from metadata is [{}] with binding [{}]", acsFromRequest, acsFromMetadata, binding);
    if (acsFromRequest != null) {
        if (!authnRequest.isSigned() && !SAMLBindingSupport.isMessageSigned(authenticationContext)) {
            val locations = StringUtils.isNotBlank(binding) ? adaptor.getAssertionConsumerServiceLocations(binding) : adaptor.getAssertionConsumerServiceLocations();
            val acsUrl = StringUtils.defaultIfBlank(acsFromRequest.getResponseLocation(), acsFromRequest.getLocation());
            val acsIndex = authnRequest instanceof AuthnRequest ? AuthnRequest.class.cast(authnRequest).getAssertionConsumerServiceIndex() : null;
            if (StringUtils.isNotBlank(acsUrl) && locations.contains(acsUrl)) {
                return buildAssertionConsumerService(binding, acsUrl, acsIndex);
            }
            if (acsIndex != null) {
                val result = adaptor.getAssertionConsumerServiceFor(binding, acsIndex);
                if (result.isPresent()) {
                    return buildAssertionConsumerService(binding, result.get(), acsIndex);
                }
            }
            val message = String.format("Assertion consumer service [%s] cannot be located in metadata [%s]", acsUrl, locations);
            throw new SamlException(message);
        }
        return acsFromRequest;
    }
    return acsFromMetadata;
}
Also used : lombok.val(lombok.val) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest)

Example 80 with AuthnRequest

use of org.opensaml.saml2.core.AuthnRequest in project cas by apereo.

the class SamlIdPUtils method storeSamlRequest.

/**
 * Store saml request.
 *
 * @param webContext         the web context
 * @param openSamlConfigBean the open saml config bean
 * @param sessionStore       the session store
 * @param context            the context
 * @throws Exception the exception
 */
public static void storeSamlRequest(final JEEContext webContext, final OpenSamlConfigBean openSamlConfigBean, final SessionStore sessionStore, final Pair<? extends SignableSAMLObject, MessageContext> context) throws Exception {
    val authnRequest = (AuthnRequest) context.getLeft();
    val messageContext = context.getValue();
    try (val writer = SamlUtils.transformSamlObject(openSamlConfigBean, authnRequest)) {
        val samlRequest = EncodingUtils.encodeBase64(writer.toString().getBytes(StandardCharsets.UTF_8));
        sessionStore.set(webContext, SamlProtocolConstants.PARAMETER_SAML_REQUEST, samlRequest);
        sessionStore.set(webContext, SamlProtocolConstants.PARAMETER_SAML_RELAY_STATE, SAMLBindingSupport.getRelayState(messageContext));
        val authnContext = SamlIdPAuthenticationContext.from(messageContext).encode();
        sessionStore.set(webContext, MessageContext.class.getName(), authnContext);
    }
}
Also used : lombok.val(lombok.val) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) MessageContext(org.opensaml.messaging.context.MessageContext)

Aggregations

AuthnRequest (org.opensaml.saml.saml2.core.AuthnRequest)120 Test (org.junit.jupiter.api.Test)37 lombok.val (lombok.val)26 Issuer (org.opensaml.saml.saml2.core.Issuer)21 AuthnRequest (org.opensaml.saml2.core.AuthnRequest)17 DateTime (org.joda.time.DateTime)16 AuthnRequestBuilder.anAuthnRequest (uk.gov.ida.saml.core.test.builders.AuthnRequestBuilder.anAuthnRequest)15 IdaAuthnRequestFromHub (uk.gov.ida.saml.hub.domain.IdaAuthnRequestFromHub)12 IdaAuthnRequestBuilder.anIdaAuthnRequest (uk.gov.ida.saml.hub.test.builders.IdaAuthnRequestBuilder.anIdaAuthnRequest)12 MessageContext (org.opensaml.messaging.context.MessageContext)10 SAMLObjectBuilder (org.opensaml.saml.common.SAMLObjectBuilder)10 Element (org.w3c.dom.Element)10 RequestedAuthnContext (org.opensaml.saml.saml2.core.RequestedAuthnContext)9 SamlRegisteredService (org.apereo.cas.support.saml.services.SamlRegisteredService)8 SamlRegisteredServiceServiceProviderMetadataFacade (org.apereo.cas.support.saml.services.idp.metadata.SamlRegisteredServiceServiceProviderMetadataFacade)8 NameIDPolicy (org.opensaml.saml.saml2.core.NameIDPolicy)8 IOException (java.io.IOException)7 XMLObject (org.opensaml.core.xml.XMLObject)7 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)6 AuthnRequestBuilder (org.opensaml.saml.saml2.core.impl.AuthnRequestBuilder)6