Search in sources :

Example 11 with RelayState

use of org.opensaml.saml.saml2.ecp.RelayState in project ddf by codice.

the class LogoutRequestService method sendLogoutRequest.

@GET
@Path("/request")
public Response sendLogoutRequest(@QueryParam("EncryptedNameIdTime") String encryptedNameIdTime) {
    String nameIdTime = encryptionService.decrypt(encryptedNameIdTime);
    String[] nameIdTimeArray = StringUtils.split(nameIdTime, "\n");
    if (nameIdTimeArray.length == 2) {
        try {
            String name = nameIdTimeArray[0];
            Long time = Long.parseLong(nameIdTimeArray[1]);
            if (System.currentTimeMillis() - time > logOutPageTimeOut) {
                String msg = String.format("Logout request was older than %sms old so it was rejected. Please refresh page and request again.", logOutPageTimeOut);
                LOGGER.info(msg);
                return buildLogoutResponse(msg);
            }
            logout();
            LogoutRequest logoutRequest = logoutMessage.buildLogoutRequest(name, getEntityId());
            String relayState = relayStates.encode(name);
            return getLogoutRequest(relayState, logoutRequest);
        } catch (Exception e) {
            String msg = "Failed to create logout request.";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        }
    } else {
        String msg = "Failed to decrypt logout request params. Invalid number of params.";
        LOGGER.info(msg);
        return buildLogoutResponse(msg);
    }
}
Also used : LogoutRequest(org.opensaml.saml.saml2.core.LogoutRequest) URISyntaxException(java.net.URISyntaxException) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) XMLStreamException(javax.xml.stream.XMLStreamException) ValidationException(ddf.security.samlp.ValidationException) IOException(java.io.IOException) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 12 with RelayState

use of org.opensaml.saml.saml2.ecp.RelayState in project ddf by codice.

the class LogoutRequestService method getSamlpPostLogoutRequest.

private Response getSamlpPostLogoutRequest(String relayState, LogoutRequest logoutRequest) throws SimpleSign.SignatureException, WSSecurityException {
    LOGGER.debug("Configuring SAML LogoutRequest for POST.");
    Document doc = DOMUtils.createDocument();
    doc.appendChild(doc.createElement("root"));
    LOGGER.debug("Signing SAML POST LogoutRequest.");
    simpleSign.signSamlObject(logoutRequest);
    LOGGER.debug("Converting SAML Request to DOM");
    String assertionResponse = DOM2Writer.nodeToString(OpenSAMLUtil.toDom(logoutRequest, doc));
    String encodedSamlRequest = Base64.getEncoder().encodeToString(assertionResponse.getBytes(StandardCharsets.UTF_8));
    String singleLogoutLocation = idpMetadata.getSingleLogoutLocation();
    String submitFormUpdated = String.format(submitForm, singleLogoutLocation, SAML_REQUEST, encodedSamlRequest, relayState);
    Response.ResponseBuilder ok = Response.ok(submitFormUpdated);
    return ok.build();
}
Also used : Response(javax.ws.rs.core.Response) LogoutResponse(org.opensaml.saml.saml2.core.LogoutResponse) Document(org.w3c.dom.Document)

Example 13 with RelayState

use of org.opensaml.saml.saml2.ecp.RelayState in project ddf by codice.

the class LogoutRequestService method getSamlpRedirectLogoutRequest.

private Response getSamlpRedirectLogoutRequest(String relayState, LogoutRequest logoutRequest) throws IOException, SimpleSign.SignatureException, WSSecurityException, URISyntaxException {
    LOGGER.debug("Configuring SAML Response for Redirect.");
    Document doc = DOMUtils.createDocument();
    doc.appendChild(doc.createElement("root"));
    URI location = logoutMessage.signSamlGetRequest(logoutRequest, new URI(idpMetadata.getSingleLogoutLocation()), relayState);
    String redirectUpdated = String.format(redirectPage, location.toString());
    Response.ResponseBuilder ok = Response.ok(redirectUpdated);
    return ok.build();
}
Also used : Response(javax.ws.rs.core.Response) LogoutResponse(org.opensaml.saml.saml2.core.LogoutResponse) Document(org.w3c.dom.Document) URI(java.net.URI)

Example 14 with RelayState

use of org.opensaml.saml.saml2.ecp.RelayState 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 15 with RelayState

use of org.opensaml.saml.saml2.ecp.RelayState in project cas by apereo.

the class SamlProfileSaml2ResponseBuilder method encode.

@Override
protected Response encode(final SamlRegisteredService service, final Response samlResponse, final HttpServletResponse httpResponse, final SamlRegisteredServiceServiceProviderMetadataFacade adaptor, final String relayState) throws SamlException {
    try {
        final HTTPPostEncoder encoder = new HTTPPostEncoder();
        encoder.setHttpServletResponse(httpResponse);
        encoder.setVelocityEngine(this.velocityEngineFactory.createVelocityEngine());
        final MessageContext outboundMessageContext = new MessageContext<>();
        SamlIdPUtils.preparePeerEntitySamlEndpointContext(outboundMessageContext, adaptor);
        outboundMessageContext.setMessage(samlResponse);
        SAMLBindingSupport.setRelayState(outboundMessageContext, relayState);
        encoder.setMessageContext(outboundMessageContext);
        encoder.initialize();
        encoder.encode();
        return samlResponse;
    } catch (final Exception e) {
        throw Throwables.propagate(e);
    }
}
Also used : HTTPPostEncoder(org.opensaml.saml.saml2.binding.encoding.impl.HTTPPostEncoder) MessageContext(org.opensaml.messaging.context.MessageContext) SamlException(org.apereo.cas.support.saml.SamlException)

Aggregations

LogoutResponse (org.opensaml.saml.saml2.core.LogoutResponse)18 Response (javax.ws.rs.core.Response)14 Test (org.junit.Test)10 Matchers.anyString (org.mockito.Matchers.anyString)10 IOException (java.io.IOException)9 ValidationException (ddf.security.samlp.ValidationException)8 LogoutRequest (org.opensaml.saml.saml2.core.LogoutRequest)8 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)7 XMLStreamException (javax.xml.stream.XMLStreamException)6 Path (javax.ws.rs.Path)5 SimpleSign (ddf.security.samlp.SimpleSign)4 GET (javax.ws.rs.GET)4 NewCookie (javax.ws.rs.core.NewCookie)4 AuthnRequest (org.opensaml.saml.saml2.core.AuthnRequest)4 SecurityServiceException (ddf.security.service.SecurityServiceException)3 URI (java.net.URI)3 POST (javax.ws.rs.POST)3 DateTime (org.joda.time.DateTime)3 URISyntaxException (java.net.URISyntaxException)2 Cookie (javax.servlet.http.Cookie)2