Search in sources :

Example 1 with MessageDecodingException

use of org.opensaml.messaging.decoder.MessageDecodingException in project cas by apereo.

the class IdPInitiatedProfileHandlerController method handleIdPInitiatedSsoRequest.

/**
 * Handle idp initiated sso requests.
 *
 * @param response the response
 * @param request  the request
 * @throws Exception the exception
 */
@GetMapping(path = SamlIdPConstants.ENDPOINT_SAML2_IDP_INIT_PROFILE_SSO)
protected void handleIdPInitiatedSsoRequest(final HttpServletResponse response, final HttpServletRequest request) throws Exception {
    // The name (i.e., the entity ID) of the service provider.
    final String providerId = CommonUtils.safeGetParameter(request, SamlIdPConstants.PROVIDER_ID);
    if (StringUtils.isBlank(providerId)) {
        LOGGER.warn("No providerId parameter given in unsolicited SSO authentication request.");
        throw new MessageDecodingException("No providerId parameter given in unsolicited SSO authentication request.");
    }
    final SamlRegisteredService registeredService = verifySamlRegisteredService(providerId);
    final Optional<SamlRegisteredServiceServiceProviderMetadataFacade> adaptor = getSamlMetadataFacadeFor(registeredService, providerId);
    if (!adaptor.isPresent()) {
        throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, "Cannot find metadata linked to " + providerId);
    }
    // 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.
    String shire = CommonUtils.safeGetParameter(request, SamlIdPConstants.SHIRE);
    final SamlRegisteredServiceServiceProviderMetadataFacade facade = adaptor.get();
    if (StringUtils.isBlank(shire)) {
        LOGGER.warn("Resolving service provider assertion consumer service URL for [{}] and binding [{}]", providerId, SAMLConstants.SAML2_POST_BINDING_URI);
        @NonNull final AssertionConsumerService acs = facade.getAssertionConsumerService(SAMLConstants.SAML2_POST_BINDING_URI);
        shire = acs.getLocation();
    }
    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");
    }
    // The target resource at the SP, or a state token generated by an SP to represent the resource.
    final String target = CommonUtils.safeGetParameter(request, SamlIdPConstants.TARGET);
    // A timestamp to help with stale request detection.
    final String time = CommonUtils.safeGetParameter(request, SamlIdPConstants.TIME);
    final SAMLObjectBuilder builder = (SAMLObjectBuilder) configBean.getBuilderFactory().getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
    final AuthnRequest authnRequest = (AuthnRequest) builder.buildObject();
    authnRequest.setAssertionConsumerServiceURL(shire);
    final SAMLObjectBuilder isBuilder = (SAMLObjectBuilder) configBean.getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
    final Issuer issuer = (Issuer) isBuilder.buildObject();
    issuer.setValue(providerId);
    authnRequest.setIssuer(issuer);
    authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
    final SAMLObjectBuilder pBuilder = (SAMLObjectBuilder) configBean.getBuilderFactory().getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
    final NameIDPolicy nameIDPolicy = (NameIDPolicy) pBuilder.buildObject();
    nameIDPolicy.setAllowCreate(Boolean.TRUE);
    authnRequest.setNameIDPolicy(nameIDPolicy);
    if (NumberUtils.isCreatable(time)) {
        authnRequest.setIssueInstant(new DateTime(TimeUnit.SECONDS.convert(Long.parseLong(time), TimeUnit.MILLISECONDS), ISOChronology.getInstanceUTC()));
    } else {
        authnRequest.setIssueInstant(new DateTime(DateTime.now(), ISOChronology.getInstanceUTC()));
    }
    authnRequest.setForceAuthn(Boolean.FALSE);
    if (StringUtils.isNotBlank(target)) {
        request.setAttribute(SamlProtocolConstants.PARAMETER_SAML_RELAY_STATE, target);
    }
    final MessageContext ctx = new MessageContext();
    ctx.setAutoCreateSubcontexts(true);
    if (facade.isAuthnRequestsSigned()) {
        samlObjectSigner.encode(authnRequest, registeredService, facade, response, request, SAMLConstants.SAML2_POST_BINDING_URI);
    }
    ctx.setMessage(authnRequest);
    ctx.getSubcontext(SAMLBindingContext.class, true).setHasBindingSignature(false);
    final Pair<SignableSAMLObject, MessageContext> pair = Pair.of(authnRequest, ctx);
    initiateAuthenticationRequest(pair, response, request);
}
Also used : SAMLBindingContext(org.opensaml.saml.common.messaging.context.SAMLBindingContext) SAMLObjectBuilder(org.opensaml.saml.common.SAMLObjectBuilder) Issuer(org.opensaml.saml.saml2.core.Issuer) NameIDPolicy(org.opensaml.saml.saml2.core.NameIDPolicy) SamlRegisteredServiceServiceProviderMetadataFacade(org.apereo.cas.support.saml.services.idp.metadata.SamlRegisteredServiceServiceProviderMetadataFacade) UnauthorizedServiceException(org.apereo.cas.services.UnauthorizedServiceException) DateTime(org.joda.time.DateTime) MessageDecodingException(org.opensaml.messaging.decoder.MessageDecodingException) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) SignableSAMLObject(org.opensaml.saml.common.SignableSAMLObject) SamlRegisteredService(org.apereo.cas.support.saml.services.SamlRegisteredService) NonNull(lombok.NonNull) AssertionConsumerService(org.opensaml.saml.saml2.metadata.AssertionConsumerService) MessageContext(org.opensaml.messaging.context.MessageContext) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Example 2 with MessageDecodingException

use of org.opensaml.messaging.decoder.MessageDecodingException in project pac4j by pac4j.

the class Pac4jHTTPPostDecoder method doDecode.

@Override
protected void doDecode() throws MessageDecodingException {
    final MessageContext messageContext = new MessageContext();
    if (!HttpConstants.HTTP_METHOD.POST.name().equalsIgnoreCase(this.context.getRequestMethod())) {
        throw new MessageDecodingException("This message decoder only supports the HTTP POST method");
    } else {
        final String relayState = this.context.getRequestParameter("RelayState");
        logger.debug("Decoded SAML relay state of: {}", relayState);
        SAMLBindingSupport.setRelayState(messageContext, relayState);
        final InputStream base64DecodedMessage = this.getBase64DecodedMessage();
        final SAMLObject inboundMessage = (SAMLObject) this.unmarshallMessage(base64DecodedMessage);
        messageContext.setMessage(inboundMessage);
        logger.debug("Decoded SAML message");
        this.populateBindingContext(messageContext);
        this.setMessageContext(messageContext);
    }
}
Also used : MessageDecodingException(org.opensaml.messaging.decoder.MessageDecodingException) SAMLObject(org.opensaml.saml.common.SAMLObject) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) MessageContext(org.opensaml.messaging.context.MessageContext)

Example 3 with MessageDecodingException

use of org.opensaml.messaging.decoder.MessageDecodingException 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)

Aggregations

MessageContext (org.opensaml.messaging.context.MessageContext)3 MessageDecodingException (org.opensaml.messaging.decoder.MessageDecodingException)3 UnauthorizedServiceException (org.apereo.cas.services.UnauthorizedServiceException)2 SAMLObjectBuilder (org.opensaml.saml.common.SAMLObjectBuilder)2 AuthnRequest (org.opensaml.saml.saml2.core.AuthnRequest)2 Issuer (org.opensaml.saml.saml2.core.Issuer)2 NameIDPolicy (org.opensaml.saml.saml2.core.NameIDPolicy)2 GetMapping (org.springframework.web.bind.annotation.GetMapping)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InputStream (java.io.InputStream)1 NonNull (lombok.NonNull)1 lombok.val (lombok.val)1 URIBuilder (org.apache.http.client.utils.URIBuilder)1 SamlRegisteredService (org.apereo.cas.support.saml.services.SamlRegisteredService)1 SamlRegisteredServiceServiceProviderMetadataFacade (org.apereo.cas.support.saml.services.idp.metadata.SamlRegisteredServiceServiceProviderMetadataFacade)1 DateTime (org.joda.time.DateTime)1 SAMLObject (org.opensaml.saml.common.SAMLObject)1 SignableSAMLObject (org.opensaml.saml.common.SignableSAMLObject)1 SAMLBindingContext (org.opensaml.saml.common.messaging.context.SAMLBindingContext)1 RequestAbstractType (org.opensaml.saml.saml2.core.RequestAbstractType)1