Search in sources :

Example 1 with SignableSAMLObject

use of org.opensaml.saml.common.SignableSAMLObject in project cas by apereo.

the class AbstractSamlProfileHandlerController method decodeSamlContextFromHttpRequest.

/**
     * Decode authentication request saml object.
     *
     * @param request the request
     * @param decoder the decoder
     * @param clazz   the clazz
     * @return the saml object
     */
protected Pair<? extends SignableSAMLObject, MessageContext> decodeSamlContextFromHttpRequest(final HttpServletRequest request, final BaseHttpServletRequestXMLMessageDecoder decoder, final Class<? extends SignableSAMLObject> clazz) {
    LOGGER.info("Received SAML profile request [{}]", request.getRequestURI());
    try {
        decoder.setHttpServletRequest(request);
        decoder.setParserPool(this.parserPool);
        decoder.initialize();
        decoder.decode();
        final MessageContext messageContext = decoder.getMessageContext();
        final SignableSAMLObject object = (SignableSAMLObject) messageContext.getMessage();
        if (object == null) {
            throw new SAMLException("No " + clazz.getName() + " could be found in this request context. Decoder has failed.");
        }
        if (!clazz.isAssignableFrom(object.getClass())) {
            throw new ClassCastException("SAML object [" + object.getClass().getName() + " type does not match " + clazz);
        }
        LOGGER.debug("Decoded SAML object [{}] from http request", object.getElementQName());
        return Pair.of(object, messageContext);
    } catch (final Exception e) {
        throw Throwables.propagate(e);
    }
}
Also used : SignableSAMLObject(org.opensaml.saml.common.SignableSAMLObject) MessageContext(org.opensaml.messaging.context.MessageContext) SAMLException(org.opensaml.saml.common.SAMLException) SamlException(org.apereo.cas.support.saml.SamlException) SAMLException(org.opensaml.saml.common.SAMLException) UnauthorizedServiceException(org.apereo.cas.services.UnauthorizedServiceException)

Example 2 with SignableSAMLObject

use of org.opensaml.saml.common.SignableSAMLObject in project ddf by codice.

the class IdpEndpoint method continueLogout.

private Response continueLogout(LogoutState logoutState, Cookie cookie, SamlProtocol.Binding incomingBinding) throws IdpException {
    if (logoutState == null) {
        throw new IdpException("Cannot continue a Logout that doesn't exist!");
    }
    try {
        SignableSAMLObject logoutObject;
        String relay = "";
        String entityId = "";
        SamlProtocol.Type samlType;
        Optional<String> nextTarget = logoutState.getNextTarget();
        if (nextTarget.isPresent()) {
            // Another target exists, log them out
            entityId = nextTarget.get();
            if (logoutState.getOriginalIssuer().equals(entityId)) {
                return continueLogout(logoutState, cookie, incomingBinding);
            }
            LogoutRequest logoutRequest = logoutMessage.buildLogoutRequest(logoutState.getNameId(), SystemBaseUrl.constructUrl("/idp/logout", true));
            logoutState.setCurrentRequestId(logoutRequest.getID());
            logoutObject = logoutRequest;
            samlType = SamlProtocol.Type.REQUEST;
            relay = "";
        } else {
            // No more targets, respond to original issuer
            entityId = logoutState.getOriginalIssuer();
            String status = logoutState.isPartialLogout() ? StatusCode.PARTIAL_LOGOUT : StatusCode.SUCCESS;
            logoutObject = logoutMessage.buildLogoutResponse(SystemBaseUrl.constructUrl("/idp/logout", true), status, logoutState.getOriginalRequestId());
            relay = logoutState.getInitialRelayState();
            LogoutState decode = logoutStates.decode(cookie.getValue(), true);
            samlType = SamlProtocol.Type.RESPONSE;
        }
        LOGGER.debug("Responding to [{}] with a [{}] and relay state [{}]", entityId, samlType, relay);
        EntityInformation.ServiceInfo entityServiceInfo = serviceProviders.get(entityId).getLogoutService(incomingBinding);
        if (entityServiceInfo == null) {
            LOGGER.info("Could not find entity service info for {}", entityId);
            return continueLogout(logoutState, cookie, incomingBinding);
        }
        switch(entityServiceInfo.getBinding()) {
            case HTTP_REDIRECT:
                return getSamlRedirectResponse(logoutObject, entityServiceInfo.getUrl(), relay, samlType);
            case HTTP_POST:
                return getSamlPostResponse(logoutObject, entityServiceInfo.getUrl(), relay, samlType);
            default:
                LOGGER.debug("No supported binding available for SP [{}].", entityId);
                logoutState.setPartialLogout(true);
                return continueLogout(logoutState, cookie, incomingBinding);
        }
    } catch (WSSecurityException | SimpleSign.SignatureException | IOException e) {
        LOGGER.debug("Error while processing logout", e);
    }
    throw new IdpException("Server error while processing logout");
}
Also used : WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) IOException(java.io.IOException) SamlProtocol(ddf.security.samlp.SamlProtocol) SignableSAMLObject(org.opensaml.saml.common.SignableSAMLObject) EntityInformation(ddf.security.samlp.impl.EntityInformation) LogoutRequest(org.opensaml.saml.saml2.core.LogoutRequest)

Example 3 with SignableSAMLObject

use of org.opensaml.saml.common.SignableSAMLObject 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 4 with SignableSAMLObject

use of org.opensaml.saml.common.SignableSAMLObject in project cas by apereo.

the class DefaultSSOSamlHttpRequestExtractor method extract.

@Audit(action = AuditableActions.SAML2_REQUEST, actionResolverName = AuditActionResolvers.SAML2_REQUEST_ACTION_RESOLVER, resourceResolverName = AuditResourceResolvers.SAML2_REQUEST_RESOURCE_RESOLVER)
@Override
@SneakyThrows
public Optional<Pair<? extends SignableSAMLObject, MessageContext>> extract(final HttpServletRequest request, final BaseHttpServletRequestXMLMessageDecoder decoder, final Class<? extends SignableSAMLObject> clazz) {
    LOGGER.trace("Received SAML profile request [{}]", request.getRequestURI());
    decoder.setHttpServletRequest(request);
    decoder.setParserPool(this.parserPool);
    decoder.initialize();
    decoder.decode();
    val messageContext = decoder.getMessageContext();
    LOGGER.trace("Locating SAML object from message context...");
    val object = (SignableSAMLObject) messageContext.getMessage();
    if (object == null) {
        LOGGER.debug("SAML object cannot be determined from the decoder [{}]", decoder.getClass().getSimpleName());
        return Optional.empty();
    }
    if (!clazz.isAssignableFrom(object.getClass())) {
        LOGGER.debug("SAML object [{}] type does not match [{}]", object.getClass().getName(), clazz);
        return Optional.empty();
    }
    LOGGER.debug("Decoded SAML object [{}] from http request", object.getElementQName());
    return Optional.of(Pair.of(object, messageContext));
}
Also used : lombok.val(lombok.val) SignableSAMLObject(org.opensaml.saml.common.SignableSAMLObject) Audit(org.apereo.inspektr.audit.annotation.Audit) SneakyThrows(lombok.SneakyThrows)

Example 5 with SignableSAMLObject

use of org.opensaml.saml.common.SignableSAMLObject in project ddf by codice.

the class LogoutMessageImpl method sendSamlLogoutRequest.

@Override
public String sendSamlLogoutRequest(LogoutWrapper request, String targetUri, boolean isSoap, @Nullable Cookie cookie) throws IOException, LogoutSecurityException {
    XMLObject xmlObject = isSoap ? SamlProtocol.createSoapMessage((SignableSAMLObject) request.getMessage()) : (XMLObject) request;
    Element requestElement = getElementFromSaml(new LogoutWrapperImpl(xmlObject));
    String requestMessage = DOM2Writer.nodeToString(requestElement);
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        HttpPost post = new HttpPost(targetUri);
        post.addHeader("Cache-Control", "no-cache, no-store");
        post.addHeader("Pragma", "no-cache");
        post.addHeader("SOAPAction", SAML_SOAP_ACTION);
        post.addHeader("Content-Type", "application/soap+xml");
        post.setEntity(new StringEntity(requestMessage, "utf-8"));
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        BasicHttpContext context = new BasicHttpContext();
        if (cookie != null) {
            BasicClientCookie basicClientCookie = new BasicClientCookie(cookie.getName(), cookie.getValue());
            basicClientCookie.setDomain(cookie.getDomain());
            basicClientCookie.setPath(cookie.getPath());
            BasicCookieStore cookieStore = new BasicCookieStore();
            cookieStore.addCookie(basicClientCookie);
            context.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
        }
        return httpClient.execute(post, responseHandler, context);
    }
}
Also used : CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) HttpPost(org.apache.http.client.methods.HttpPost) BasicHttpContext(org.apache.http.protocol.BasicHttpContext) Element(org.w3c.dom.Element) BasicResponseHandler(org.apache.http.impl.client.BasicResponseHandler) XMLObject(org.opensaml.core.xml.XMLObject) BasicClientCookie(org.apache.http.impl.cookie.BasicClientCookie) StringEntity(org.apache.http.entity.StringEntity) BasicCookieStore(org.apache.http.impl.client.BasicCookieStore) SignableSAMLObject(org.opensaml.saml.common.SignableSAMLObject)

Aggregations

SignableSAMLObject (org.opensaml.saml.common.SignableSAMLObject)11 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)5 PrivateKey (java.security.PrivateKey)4 X509Certificate (java.security.cert.X509Certificate)4 CryptoType (org.apache.wss4j.common.crypto.CryptoType)4 BasicX509Credential (org.opensaml.security.x509.BasicX509Credential)4 X509KeyInfoGeneratorFactory (org.opensaml.xmlsec.keyinfo.impl.X509KeyInfoGeneratorFactory)4 KeyInfo (org.opensaml.xmlsec.signature.KeyInfo)4 Signature (org.opensaml.xmlsec.signature.Signature)4 IOException (java.io.IOException)2 UnauthorizedServiceException (org.apereo.cas.services.UnauthorizedServiceException)2 XMLObject (org.opensaml.core.xml.XMLObject)2 MessageContext (org.opensaml.messaging.context.MessageContext)2 LogoutSecurityException (ddf.security.samlp.LogoutSecurityException)1 SamlProtocol (ddf.security.samlp.SamlProtocol)1 EntityInformation (ddf.security.samlp.impl.EntityInformation)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 DestroyFailedException (javax.security.auth.DestroyFailedException)1 CallbackHandler (javax.security.auth.callback.CallbackHandler)1 NonNull (lombok.NonNull)1