Search in sources :

Example 96 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project ddf by codice.

the class LogoutMessageImpl method getElementFromSaml.

@Override
public Element getElementFromSaml(LogoutWrapper xmlObject) throws LogoutSecurityException {
    try {
        Document doc = DOMUtils.createDocument();
        doc.appendChild(doc.createElement("root"));
        return OpenSAMLUtil.toDom((XMLObject) xmlObject.getMessage(), doc);
    } catch (WSSecurityException e) {
        throw new LogoutSecurityException(e);
    }
}
Also used : WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) Document(org.w3c.dom.Document) LogoutSecurityException(ddf.security.samlp.LogoutSecurityException)

Example 97 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project ddf by codice.

the class LogoutMessageImpl method extractResponse.

private LogoutWrapper<LogoutResponse> extractResponse(String samlObject) throws LogoutSecurityException, XMLStreamException {
    try {
        Document responseDoc = StaxUtils.read(new ByteArrayInputStream(samlObject.getBytes(StandardCharsets.UTF_8)));
        XMLObject responseXmlObject = OpenSAMLUtil.fromDom(responseDoc.getDocumentElement());
        if (LogoutResponse.class.isAssignableFrom(responseXmlObject.getClass())) {
            return new LogoutWrapperImpl<>((LogoutResponse) responseXmlObject);
        }
        return null;
    } catch (WSSecurityException e) {
        throw new LogoutSecurityException(e);
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) XMLObject(org.opensaml.core.xml.XMLObject) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) Document(org.w3c.dom.Document) LogoutSecurityException(ddf.security.samlp.LogoutSecurityException)

Example 98 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project ddf by codice.

the class PaosInInterceptor method handleMessage.

@Override
public void handleMessage(Message message) throws Fault {
    List authHeader = (List) ((Map) message.getExchange().getOutMessage().get(Message.PROTOCOL_HEADERS)).get("Authorization");
    String authorization = null;
    if (authHeader != null && authHeader.size() > 0) {
        authorization = (String) authHeader.get(0);
    }
    InputStream content = message.getContent(InputStream.class);
    String contentType = (String) message.get(Message.CONTENT_TYPE);
    if (contentType == null || !contentType.contains(APPLICATION_VND_PAOS_XML)) {
        return;
    }
    try {
        SOAPPart soapMessage = SamlProtocol.parseSoapMessage(IOUtils.toString(content, StandardCharsets.UTF_8));
        Iterator iterator = soapMessage.getEnvelope().getHeader().examineAllHeaderElements();
        IDPEntry idpEntry = null;
        String relayState = "";
        String responseConsumerURL = "";
        String messageId = "";
        while (iterator.hasNext()) {
            Element soapHeaderElement = (SOAPHeaderElement) iterator.next();
            if (RELAY_STATE.equals(soapHeaderElement.getLocalName())) {
                relayState = DOM2Writer.nodeToString(soapHeaderElement);
            } else if (REQUEST.equals(soapHeaderElement.getLocalName()) && soapHeaderElement.getNamespaceURI().equals(URN_OASIS_NAMES_TC_SAML_2_0_PROFILES_SSO_ECP)) {
                try {
                    soapHeaderElement = SamlProtocol.convertDomImplementation(soapHeaderElement);
                    Request ecpRequest = (Request) OpenSAMLUtil.fromDom(soapHeaderElement);
                    IDPList idpList = ecpRequest.getIDPList();
                    if (idpList == null) {
                        throw new Fault(new AccessDeniedException(IDP_SERVER_FAILURE_MSG));
                    }
                    List<IDPEntry> idpEntrys = idpList.getIDPEntrys();
                    if (idpEntrys == null || idpEntrys.size() == 0) {
                        throw new Fault(new AccessDeniedException(IDP_SERVER_FAILURE_MSG));
                    }
                    // choose the right entry, probably need to do something better than select the first
                    // one
                    // but the spec doesn't specify how this is supposed to be done
                    idpEntry = idpEntrys.get(0);
                } catch (WSSecurityException e) {
                    // TODO figure out IdP alternatively
                    LOGGER.info("Unable to determine IdP appropriately. ECP connection will fail. SP may be incorrectly configured. Contact the administrator for the remote system.");
                }
            } else if (REQUEST.equals(soapHeaderElement.getLocalName()) && soapHeaderElement.getNamespaceURI().equals(URN_LIBERTY_PAOS_2003_08)) {
                responseConsumerURL = soapHeaderElement.getAttribute(RESPONSE_CONSUMER_URL);
                messageId = soapHeaderElement.getAttribute(MESSAGE_ID);
            }
        }
        if (idpEntry == null) {
            throw new Fault(new AccessDeniedException(IDP_SERVER_FAILURE_MSG));
        }
        String token = createToken(authorization);
        checkAuthnRequest(soapMessage);
        Element authnRequestElement = SamlProtocol.getDomElement(soapMessage.getEnvelope().getBody().getFirstChild());
        String loc = idpEntry.getLoc();
        String soapRequest = buildSoapMessage(token, relayState, authnRequestElement, null);
        HttpResponseWrapper httpResponse = getHttpResponse(loc, soapRequest, null);
        InputStream httpResponseContent = httpResponse.content;
        SOAPPart idpSoapResponse = SamlProtocol.parseSoapMessage(IOUtils.toString(httpResponseContent, StandardCharsets.UTF_8));
        Iterator responseHeaderElements = idpSoapResponse.getEnvelope().getHeader().examineAllHeaderElements();
        String newRelayState = "";
        while (responseHeaderElements.hasNext()) {
            SOAPHeaderElement soapHeaderElement = (SOAPHeaderElement) responseHeaderElements.next();
            if (RESPONSE.equals(soapHeaderElement.getLocalName())) {
                String assertionConsumerServiceURL = soapHeaderElement.getAttribute(ASSERTION_CONSUMER_SERVICE_URL);
                if (!responseConsumerURL.equals(assertionConsumerServiceURL)) {
                    String soapFault = buildSoapFault(ECP_RESPONSE, "The responseConsumerURL does not match the assertionConsumerServiceURL.");
                    httpResponse = getHttpResponse(responseConsumerURL, soapFault, null);
                    message.setContent(InputStream.class, httpResponse.content);
                    return;
                }
            } else if (RELAY_STATE.equals(soapHeaderElement.getLocalName())) {
                newRelayState = DOM2Writer.nodeToString(soapHeaderElement);
                if (StringUtils.isNotEmpty(relayState) && !relayState.equals(newRelayState)) {
                    LOGGER.debug("RelayState does not match between ECP request and response");
                }
                if (StringUtils.isNotEmpty(relayState)) {
                    newRelayState = relayState;
                }
            }
        }
        checkSamlpResponse(idpSoapResponse);
        Element samlpResponseElement = SamlProtocol.getDomElement(idpSoapResponse.getEnvelope().getBody().getFirstChild());
        XMLObject paosResponse = null;
        if (StringUtils.isNotEmpty(messageId)) {
            paosResponse = getPaosResponse(messageId);
        }
        String soapResponse = buildSoapMessage(null, newRelayState, samlpResponseElement, paosResponse);
        httpResponse = getHttpResponse(responseConsumerURL, soapResponse, message.getExchange().getOutMessage());
        if (httpResponse.statusCode < 400) {
            httpResponseContent = httpResponse.content;
            message.setContent(InputStream.class, httpResponseContent);
            Map<String, List<String>> headers = new HashMap<>();
            message.put(Message.PROTOCOL_HEADERS, headers);
            httpResponse.headers.forEach((entry) -> headers.put(entry.getKey(), // CXF Expects pairs of <String, List<String>>
            entry.getValue() instanceof List ? ((List<Object>) entry.getValue()).stream().map(String::valueOf).collect(Collectors.toList()) : Lists.newArrayList(String.valueOf(entry.getValue()))));
        } else {
            throw new Fault(new AccessDeniedException("Unable to complete SAML ECP connection due to an error."));
        }
    } catch (IOException e) {
        LOGGER.debug("Error encountered while performing ECP handshake.", e);
    } catch (XMLStreamException | SOAPException e) {
        throw new Fault(new AccessDeniedException("Unable to complete SAML ECP connection. The server's response was not in the correct format."));
    } catch (WSSecurityException e) {
        throw new Fault(new AccessDeniedException("Unable to complete SAML ECP connection. Unable to send SOAP request messages."));
    }
}
Also used : SOAPHeaderElement(javax.xml.soap.SOAPHeaderElement) AccessDeniedException(org.apache.cxf.interceptor.security.AccessDeniedException) HashMap(java.util.HashMap) InputStream(java.io.InputStream) SOAPHeaderElement(javax.xml.soap.SOAPHeaderElement) Element(org.w3c.dom.Element) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) Request(org.opensaml.saml.saml2.ecp.Request) HttpRequest(com.google.api.client.http.HttpRequest) IDPList(org.opensaml.saml.saml2.core.IDPList) XMLObject(org.opensaml.core.xml.XMLObject) Fault(org.apache.cxf.interceptor.Fault) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) IOException(java.io.IOException) XMLStreamException(javax.xml.stream.XMLStreamException) SOAPException(javax.xml.soap.SOAPException) SOAPPart(javax.xml.soap.SOAPPart) Iterator(java.util.Iterator) IDPList(org.opensaml.saml.saml2.core.IDPList) List(java.util.List) XMLObject(org.opensaml.core.xml.XMLObject) IDPEntry(org.opensaml.saml.saml2.core.IDPEntry)

Example 99 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project ddf by codice.

the class PaosInInterceptor method checkAuthnRequest.

private void checkAuthnRequest(SOAPPart soapRequest) throws IOException {
    XMLObject authnXmlObj = null;
    try {
        Node node = soapRequest.getEnvelope().getBody().getFirstChild();
        authnXmlObj = SamlProtocol.getXmlObjectFromNode(node);
    } catch (WSSecurityException | SOAPException | XMLStreamException ex) {
        throw new IOException("Unable to convert AuthnRequest document to XMLObject.");
    }
    if (authnXmlObj == null) {
        throw new IOException("AuthnRequest object is not Found.");
    }
    if (!(authnXmlObj instanceof AuthnRequest)) {
        throw new IOException("SAMLRequest object is not AuthnRequest.");
    }
}
Also used : XMLStreamException(javax.xml.stream.XMLStreamException) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) Node(org.w3c.dom.Node) SOAPException(javax.xml.soap.SOAPException) XMLObject(org.opensaml.core.xml.XMLObject) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) IOException(java.io.IOException)

Example 100 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project ddf by codice.

the class SamlAssertionValidatorImpl method validate.

/**
 * Validates a SAMLAuthenticationToken by checking it's signature against the configured system
 * certs.
 *
 * @param token token to validate
 * @throws AuthenticationFailureException thrown when the cert fails to validate
 */
@Override
public void validate(SAMLAuthenticationToken token) throws AuthenticationFailureException {
    try {
        LOGGER.debug("Validation received SAML Assertion");
        PrincipalCollection principalCollection = (PrincipalCollection) token.getCredentials();
        Collection<SecurityAssertion> securityAssertions = principalCollection.byType(SecurityAssertion.class);
        SecurityAssertion securityAssertion = null;
        for (SecurityAssertion assertion : securityAssertions) {
            if (SecurityAssertionSaml.SAML2_TOKEN_TYPE.equals(assertion.getTokenType())) {
                securityAssertion = assertion;
                break;
            }
        }
        if (securityAssertion == null) {
            throw new AuthenticationFailureException("Unable to validate SAML token. Token is not SAML.");
        }
        SamlAssertionWrapper assertion = new SamlAssertionWrapper((Element) securityAssertion.getToken());
        // get the crypto junk
        Crypto crypto = getSignatureCrypto();
        Response samlResponse = createSamlResponse(token.getRequestURI(), assertion.getIssuerString(), createStatus(SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null));
        BUILDER.get().reset();
        Document doc = BUILDER.get().newDocument();
        Element policyElement = OpenSAMLUtil.toDom(samlResponse, doc);
        doc.appendChild(policyElement);
        Credential credential = new Credential();
        credential.setSamlAssertion(assertion);
        RequestData requestData = new RequestData();
        requestData.setWsDocInfo(new WSDocInfo(samlResponse.getDOM().getOwnerDocument()));
        requestData.setSigVerCrypto(crypto);
        WSSConfig wssConfig = WSSConfig.getNewInstance();
        requestData.setWssConfig(wssConfig);
        X509Certificate[] x509Certs = token.getX509Certs();
        requestData.setTlsCerts(x509Certs);
        validateHolderOfKeyConfirmation(assertion, x509Certs);
        if (assertion.isSigned()) {
            // Verify the signature
            WSSSAMLKeyInfoProcessor wsssamlKeyInfoProcessor = new WSSSAMLKeyInfoProcessor(requestData);
            assertion.verifySignature(wsssamlKeyInfoProcessor, crypto);
            assertion.parseSubject(new WSSSAMLKeyInfoProcessor(requestData), requestData.getSigVerCrypto(), requestData.getCallbackHandler());
        }
        assertionValidator.validate(credential, requestData);
    } catch (SecurityServiceException e) {
        LOGGER.debug("Unable to get subject from SAML request.", e);
        throw new AuthenticationFailureException(e);
    } catch (WSSecurityException e) {
        LOGGER.debug("Unable to read/validate security token from request.", e);
        throw new AuthenticationFailureException(e);
    }
}
Also used : WSDocInfo(org.apache.wss4j.dom.WSDocInfo) Credential(org.apache.wss4j.dom.validate.Credential) SecurityServiceException(ddf.security.service.SecurityServiceException) Element(org.w3c.dom.Element) PrincipalCollection(org.apache.shiro.subject.PrincipalCollection) SamlAssertionWrapper(org.apache.wss4j.common.saml.SamlAssertionWrapper) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) AuthenticationFailureException(org.codice.ddf.platform.filter.AuthenticationFailureException) SecurityAssertion(ddf.security.assertion.SecurityAssertion) Document(org.w3c.dom.Document) X509Certificate(java.security.cert.X509Certificate) Response(org.opensaml.saml.saml2.core.Response) Crypto(org.apache.wss4j.common.crypto.Crypto) WSSConfig(org.apache.wss4j.dom.engine.WSSConfig) RequestData(org.apache.wss4j.dom.handler.RequestData) WSSSAMLKeyInfoProcessor(org.apache.wss4j.dom.saml.WSSSAMLKeyInfoProcessor)

Aggregations

WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)241 Element (org.w3c.dom.Element)72 Document (org.w3c.dom.Document)53 IOException (java.io.IOException)51 Crypto (org.apache.wss4j.common.crypto.Crypto)50 SamlAssertionWrapper (org.apache.wss4j.common.saml.SamlAssertionWrapper)39 Credential (org.apache.wss4j.dom.validate.Credential)37 RequestData (org.apache.wss4j.dom.handler.RequestData)36 X509Certificate (java.security.cert.X509Certificate)31 Response (org.opensaml.saml.saml2.core.Response)31 SAMLCallback (org.apache.wss4j.common.saml.SAMLCallback)25 DateTime (org.joda.time.DateTime)22 XMLObject (org.opensaml.core.xml.XMLObject)22 XMLStreamException (javax.xml.stream.XMLStreamException)21 SecurityToken (org.apache.cxf.ws.security.tokenstore.SecurityToken)21 Fault (org.apache.cxf.interceptor.Fault)20 SOAPException (javax.xml.soap.SOAPException)19 CallbackHandler (javax.security.auth.callback.CallbackHandler)18 ReceivedToken (org.apache.cxf.sts.request.ReceivedToken)17 InputStream (java.io.InputStream)16