Search in sources :

Example 1 with IDPEntry

use of org.opensaml.saml.saml2.core.IDPEntry 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, Charset.forName("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("Unable to complete SAML ECP connection. Unable to determine IdP server."));
                    }
                    List<IDPEntry> idpEntrys = idpList.getIDPEntrys();
                    if (idpEntrys == null || idpEntrys.size() == 0) {
                        throw new Fault(new AccessDeniedException("Unable to complete SAML ECP connection. Unable to determine IdP server."));
                    }
                    //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("Unable to complete SAML ECP connection. Unable to determine IdP server."));
        }
        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, Charset.forName("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());
        Response 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);
        } 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) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) SOAPHeaderElement(javax.xml.soap.SOAPHeaderElement) Element(org.w3c.dom.Element) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) HttpRequest(com.google.api.client.http.HttpRequest) Request(org.opensaml.saml.saml2.ecp.Request) IDPList(org.opensaml.saml.saml2.core.IDPList) Fault(org.apache.cxf.interceptor.Fault) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) IOException(java.io.IOException) HttpResponse(com.google.api.client.http.HttpResponse) Response(ddf.security.liberty.paos.Response) 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) IDPEntry(org.opensaml.saml.saml2.core.IDPEntry)

Example 2 with IDPEntry

use of org.opensaml.saml.saml2.core.IDPEntry in project ddf by codice.

the class IdpHandler method createEcpRequest.

private String createEcpRequest() throws WSSecurityException {
    org.opensaml.saml.saml2.ecp.impl.RequestBuilder requestBuilder = new org.opensaml.saml.saml2.ecp.impl.RequestBuilder();
    org.opensaml.saml.saml2.ecp.Request ecpRequest = requestBuilder.buildObject();
    ecpRequest.setSOAP11MustUnderstand(true);
    ecpRequest.setSOAP11Actor(HTTP_SCHEMAS_XMLSOAP_ORG_SOAP_ACTOR_NEXT);
    Issuer issuer = issuerBuilder.buildObject();
    issuer.setValue(getSpIssuerId());
    ecpRequest.setIssuer(issuer);
    IDPListBuilder idpListBuilder = new IDPListBuilder();
    IDPList idpList = idpListBuilder.buildObject();
    IDPEntryBuilder idpEntryBuilder = new IDPEntryBuilder();
    IDPEntry idpEntry = idpEntryBuilder.buildObject();
    idpEntry.setProviderID(idpMetadata.getEntityId());
    idpEntry.setName(idpMetadata.getSingleSignOnLocation());
    idpEntry.setLoc(idpMetadata.getSingleSignOnLocation());
    idpList.getIDPEntrys().add(idpEntry);
    ecpRequest.setIDPList(idpList);
    return convertXmlObjectToString(ecpRequest);
}
Also used : IDPEntryBuilder(org.opensaml.saml.saml2.core.impl.IDPEntryBuilder) RequestBuilder(ddf.security.liberty.paos.impl.RequestBuilder) Issuer(org.opensaml.saml.saml2.core.Issuer) IDPList(org.opensaml.saml.saml2.core.IDPList) IDPEntry(org.opensaml.saml.saml2.core.IDPEntry) IDPListBuilder(org.opensaml.saml.saml2.core.impl.IDPListBuilder)

Aggregations

IDPEntry (org.opensaml.saml.saml2.core.IDPEntry)2 IDPList (org.opensaml.saml.saml2.core.IDPList)2 HttpRequest (com.google.api.client.http.HttpRequest)1 HttpResponse (com.google.api.client.http.HttpResponse)1 Response (ddf.security.liberty.paos.Response)1 RequestBuilder (ddf.security.liberty.paos.impl.RequestBuilder)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 Iterator (java.util.Iterator)1 List (java.util.List)1 SOAPException (javax.xml.soap.SOAPException)1 SOAPHeaderElement (javax.xml.soap.SOAPHeaderElement)1 SOAPPart (javax.xml.soap.SOAPPart)1 XMLStreamException (javax.xml.stream.XMLStreamException)1 Fault (org.apache.cxf.interceptor.Fault)1 AccessDeniedException (org.apache.cxf.interceptor.security.AccessDeniedException)1 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)1 AuthnRequest (org.opensaml.saml.saml2.core.AuthnRequest)1 Issuer (org.opensaml.saml.saml2.core.Issuer)1