Search in sources :

Example 21 with Request

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

the class LogoutRequestServiceTest method testSendLogoutRequestTimeout.

@Test
public void testSendLogoutRequestTimeout() throws Exception {
    Long badTime = (time - TimeUnit.DAYS.toMillis(1));
    String encryptedNameIdWithTime = nameId + "\n" + badTime;
    when(encryptionService.decrypt(any(String.class))).thenReturn(nameId + "\n" + badTime);
    Response response = logoutRequestService.sendLogoutRequest(encryptedNameIdWithTime);
    assertEquals(Response.Status.SEE_OTHER.getStatusCode(), response.getStatus());
    String msg = String.format("Logout request was older than %sms old so it was rejected. Please refresh page and request again.", LOGOUT_PAGE_TIMEOUT).replaceAll(" ", "+");
    assertTrue("Expected message containing " + msg, response.getLocation().getQuery().contains(msg));
}
Also used : LogoutResponse(org.opensaml.saml.saml2.core.LogoutResponse) Response(javax.ws.rs.core.Response) Matchers.anyString(org.mockito.Matchers.anyString) Test(org.junit.Test)

Example 22 with Request

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

the class LogoutRequestServiceTest method testGetLogoutRequestNotParsable.

@Test
public void testGetLogoutRequestNotParsable() throws Exception {
    String signature = "signature";
    String signatureAlgorithm = "sha1";
    String relayState = UUID.randomUUID().toString();
    String deflatedSamlRequest = RestSecurity.deflateAndBase64Encode("deflatedSamlRequest");
    when(logoutMessage.extractSamlLogoutRequest(eq("deflatedSamlRequest"))).thenReturn(null);
    Response response = logoutRequestService.getLogoutRequest(deflatedSamlRequest, null, relayState, signatureAlgorithm, signature);
    assertEquals(Response.Status.SEE_OTHER.getStatusCode(), response.getStatus());
    String msg = "Unable to parse logout request.".replaceAll(" ", "+");
    assertTrue("Expected message containing " + msg, response.getLocation().getQuery().contains(msg));
}
Also used : LogoutResponse(org.opensaml.saml.saml2.core.LogoutResponse) Response(javax.ws.rs.core.Response) Matchers.anyString(org.mockito.Matchers.anyString) Test(org.junit.Test)

Example 23 with Request

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

the class PaosInInterceptor method getHttpResponse.

HttpResponseWrapper getHttpResponse(String responseConsumerURL, String soapResponse, Message message) throws IOException {
    //This used to use the ApacheHttpTransport which appeared to not work with 2 way TLS auth but this one does
    HttpTransport httpTransport = new NetHttpTransport();
    HttpContent httpContent = new InputStreamContent(TEXT_XML, new ByteArrayInputStream(soapResponse.getBytes("UTF-8")));
    //this handles redirects for us
    ((InputStreamContent) httpContent).setRetrySupported(true);
    HttpRequest httpRequest = httpTransport.createRequestFactory().buildPostRequest(new GenericUrl(responseConsumerURL), httpContent);
    HttpUnsuccessfulResponseHandler httpUnsuccessfulResponseHandler = (request, response, supportsRetry) -> {
        String redirectLocation = response.getHeaders().getLocation();
        if (request.getFollowRedirects() && HttpStatusCodes.isRedirect(response.getStatusCode()) && redirectLocation != null) {
            String method = (String) message.get(Message.HTTP_REQUEST_METHOD);
            HttpContent content = null;
            if (!isRedirectable(method)) {
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                message.setContent(OutputStream.class, byteArrayOutputStream);
                BodyWriter bodyWriter = new BodyWriter();
                bodyWriter.handleMessage(message);
                content = new InputStreamContent((String) message.get(Message.CONTENT_TYPE), new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
            }
            // resolve the redirect location relative to the current location
            request.setUrl(new GenericUrl(request.getUrl().toURL(redirectLocation)));
            request.setRequestMethod(method);
            request.setContent(content);
            // remove Authorization and If-* headers
            request.getHeaders().setAuthorization((String) null);
            request.getHeaders().setIfMatch(null);
            request.getHeaders().setIfNoneMatch(null);
            request.getHeaders().setIfModifiedSince(null);
            request.getHeaders().setIfUnmodifiedSince(null);
            request.getHeaders().setIfRange(null);
            request.getHeaders().setCookie((String) ((List) response.getHeaders().get("set-cookie")).get(0));
            return true;
        }
        return false;
    };
    httpRequest.setUnsuccessfulResponseHandler(httpUnsuccessfulResponseHandler);
    httpRequest.getHeaders().put(SOAP_ACTION, HTTP_WWW_OASIS_OPEN_ORG_COMMITTEES_SECURITY);
    //has 20 second timeout by default
    HttpResponse httpResponse = httpRequest.execute();
    HttpResponseWrapper httpResponseWrapper = new HttpResponseWrapper();
    httpResponseWrapper.statusCode = httpResponse.getStatusCode();
    httpResponseWrapper.content = httpResponse.getContent();
    return httpResponseWrapper;
}
Also used : HttpRequest(com.google.api.client.http.HttpRequest) RestSecurity(org.codice.ddf.security.common.jaxrs.RestSecurity) StringUtils(org.apache.commons.lang.StringUtils) ByteArrayOutputStream(java.io.ByteArrayOutputStream) SOAPHeaderElement(javax.xml.soap.SOAPHeaderElement) DOMUtils(org.apache.cxf.helpers.DOMUtils) ResponseBuilder(ddf.security.liberty.paos.impl.ResponseBuilder) SOAPException(javax.xml.soap.SOAPException) DOM2Writer(org.apache.wss4j.common.util.DOM2Writer) IDPList(org.opensaml.saml.saml2.core.IDPList) LoggerFactory(org.slf4j.LoggerFactory) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) AbstractPhaseInterceptor(org.apache.cxf.phase.AbstractPhaseInterceptor) HttpRequest(com.google.api.client.http.HttpRequest) SamlProtocol(ddf.security.samlp.SamlProtocol) HttpResponse(com.google.api.client.http.HttpResponse) IDPEntry(org.opensaml.saml.saml2.core.IDPEntry) ByteArrayInputStream(java.io.ByteArrayInputStream) Charset(java.nio.charset.Charset) Fault(org.apache.cxf.interceptor.Fault) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) Document(org.w3c.dom.Document) Map(java.util.Map) XMLStreamException(javax.xml.stream.XMLStreamException) Node(org.w3c.dom.Node) HttpUnsuccessfulResponseHandler(com.google.api.client.http.HttpUnsuccessfulResponseHandler) GenericUrl(com.google.api.client.http.GenericUrl) OpenSAMLUtil(org.apache.wss4j.common.saml.OpenSAMLUtil) XMLObject(org.opensaml.core.xml.XMLObject) HttpContent(com.google.api.client.http.HttpContent) OutputStream(java.io.OutputStream) NetHttpTransport(com.google.api.client.http.javanet.NetHttpTransport) Response(ddf.security.liberty.paos.Response) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) Message(org.apache.cxf.message.Message) HttpTransport(com.google.api.client.http.HttpTransport) IOException(java.io.IOException) AccessDeniedException(org.apache.cxf.interceptor.security.AccessDeniedException) StandardCharsets(java.nio.charset.StandardCharsets) Request(org.opensaml.saml.saml2.ecp.Request) IOUtils(org.apache.commons.io.IOUtils) Base64(java.util.Base64) List(java.util.List) SOAPPart(javax.xml.soap.SOAPPart) Element(org.w3c.dom.Element) HttpStatusCodes(com.google.api.client.http.HttpStatusCodes) InputStreamContent(com.google.api.client.http.InputStreamContent) InputStream(java.io.InputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) HttpUnsuccessfulResponseHandler(com.google.api.client.http.HttpUnsuccessfulResponseHandler) HttpResponse(com.google.api.client.http.HttpResponse) GenericUrl(com.google.api.client.http.GenericUrl) ByteArrayOutputStream(java.io.ByteArrayOutputStream) NetHttpTransport(com.google.api.client.http.javanet.NetHttpTransport) HttpTransport(com.google.api.client.http.HttpTransport) ByteArrayInputStream(java.io.ByteArrayInputStream) NetHttpTransport(com.google.api.client.http.javanet.NetHttpTransport) InputStreamContent(com.google.api.client.http.InputStreamContent) HttpContent(com.google.api.client.http.HttpContent)

Example 24 with Request

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

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

the class AttributeQueryClaimsHandler method getAttributes.

/**
     * Gets the attributes for the supplied user from the external attribute store.
     * Returns null if the AttributeQueryClient is null.
     *
     * @param nameId used for the request.
     * @return The collection of attributes retrieved from the external attribute store.
     * @throws URISyntaxException
     */
protected ProcessedClaimCollection getAttributes(String nameId) throws URISyntaxException {
    ProcessedClaimCollection claimCollection = new ProcessedClaimCollection();
    LOGGER.debug("Sending AttributeQuery Request.");
    AttributeQueryClient attributeQueryClient;
    Assertion assertion;
    try {
        attributeQueryClient = createAttributeQueryClient(simpleSign, externalAttributeStoreUrl, issuer, destination);
        if (attributeQueryClient == null) {
            return null;
        }
        assertion = attributeQueryClient.query(nameId);
        if (assertion != null) {
            createClaims(claimCollection, assertion);
        }
    } catch (AttributeQueryException ex) {
        LOGGER.info("Error occurred in AttributeQueryClient, did not retrieve response. Set log level for \"org.codice.ddf.security.claims.attributequery.common\" to DEBUG for more information.");
        LOGGER.debug("Error occurred in AttributeQueryClient, did not retrieve response.", ex);
    }
    return claimCollection;
}
Also used : ProcessedClaimCollection(org.apache.cxf.sts.claims.ProcessedClaimCollection) Assertion(org.opensaml.saml.saml2.core.Assertion)

Aggregations

AuthnRequest (org.opensaml.saml.saml2.core.AuthnRequest)24 IOException (java.io.IOException)13 LogoutResponse (org.opensaml.saml.saml2.core.LogoutResponse)13 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)12 SamlRegisteredServiceServiceProviderMetadataFacade (org.apereo.cas.support.saml.services.idp.metadata.SamlRegisteredServiceServiceProviderMetadataFacade)11 Test (org.junit.Test)10 ValidationException (ddf.security.samlp.ValidationException)9 Response (javax.ws.rs.core.Response)9 SamlRegisteredService (org.apereo.cas.support.saml.services.SamlRegisteredService)9 Assertion (org.jasig.cas.client.validation.Assertion)9 MessageContext (org.opensaml.messaging.context.MessageContext)9 Assertion (org.opensaml.saml.saml2.core.Assertion)9 Document (org.w3c.dom.Document)9 XMLStreamException (javax.xml.stream.XMLStreamException)8 LogoutRequest (org.opensaml.saml.saml2.core.LogoutRequest)8 NameID (org.opensaml.saml.saml2.core.NameID)7 ByteArrayInputStream (java.io.ByteArrayInputStream)6 SimpleSign (ddf.security.samlp.SimpleSign)5 ZonedDateTime (java.time.ZonedDateTime)5 Path (javax.ws.rs.Path)5