Search in sources :

Example 11 with Request

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

the class BaseSamlRegisteredServiceAttributeReleasePolicy method getAttributesInternal.

@Override
protected Map<String, Object> getAttributesInternal(final Map<String, Object> attrs, final RegisteredService service) {
    if (service instanceof SamlRegisteredService) {
        final SamlRegisteredService saml = (SamlRegisteredService) service;
        final HttpServletRequest request = WebUtils.getHttpServletRequestFromRequestAttributes();
        if (request == null) {
            LOGGER.warn("Could not locate the request context to process attributes");
            return super.getAttributesInternal(attrs, service);
        }
        String entityId = request.getParameter(SamlProtocolConstants.PARAMETER_ENTITY_ID);
        if (StringUtils.isBlank(entityId)) {
            final String svcParam = request.getParameter(CasProtocolConstants.PARAMETER_SERVICE);
            if (StringUtils.isNotBlank(svcParam)) {
                try {
                    final URIBuilder builder = new URIBuilder(svcParam);
                    entityId = builder.getQueryParams().stream().filter(p -> p.getName().equals(SamlProtocolConstants.PARAMETER_ENTITY_ID)).map(NameValuePair::getValue).findFirst().orElse(StringUtils.EMPTY);
                } catch (final Exception e) {
                    LOGGER.error(e.getMessage());
                }
            }
        }
        final ApplicationContext ctx = ApplicationContextProvider.getApplicationContext();
        if (ctx == null) {
            LOGGER.warn("Could not locate the application context to process attributes");
            return super.getAttributesInternal(attrs, service);
        }
        final SamlRegisteredServiceCachingMetadataResolver resolver = ctx.getBean("defaultSamlRegisteredServiceCachingMetadataResolver", SamlRegisteredServiceCachingMetadataResolver.class);
        final Optional<SamlRegisteredServiceServiceProviderMetadataFacade> facade = SamlRegisteredServiceServiceProviderMetadataFacade.get(resolver, saml, entityId);
        if (facade == null || !facade.isPresent()) {
            LOGGER.warn("Could not locate metadata for [{}] to process attributes", entityId);
            return super.getAttributesInternal(attrs, service);
        }
        final EntityDescriptor input = facade.get().getEntityDescriptor();
        if (input == null) {
            LOGGER.warn("Could not locate entity descriptor for [{}] to process attributes", entityId);
            return super.getAttributesInternal(attrs, service);
        }
        return getAttributesForSamlRegisteredService(attrs, saml, ctx, resolver, facade.get(), input);
    }
    return super.getAttributesInternal(attrs, service);
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) EntityDescriptor(org.opensaml.saml.saml2.metadata.EntityDescriptor) ApplicationContext(org.springframework.context.ApplicationContext) SamlRegisteredServiceServiceProviderMetadataFacade(org.apereo.cas.support.saml.services.idp.metadata.SamlRegisteredServiceServiceProviderMetadataFacade) SamlRegisteredServiceCachingMetadataResolver(org.apereo.cas.support.saml.services.idp.metadata.cache.SamlRegisteredServiceCachingMetadataResolver) URIBuilder(org.apache.http.client.utils.URIBuilder)

Example 12 with Request

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

the class WsFederationHelper method parseTokenFromString.

/**
     * parseTokenFromString converts a raw wresult and extracts it into an assertion.
     *
     * @param wresult the raw token returned by the IdP
     * @param config  the config
     * @return an assertion
     */
public Assertion parseTokenFromString(final String wresult, final WsFederationConfiguration config) {
    LOGGER.debug("Result token received from ADFS is [{}]", wresult);
    try (InputStream in = new ByteArrayInputStream(wresult.getBytes(StandardCharsets.UTF_8))) {
        LOGGER.debug("Parsing token into a document");
        final Document document = configBean.getParserPool().parse(in);
        final Element metadataRoot = document.getDocumentElement();
        final UnmarshallerFactory unmarshallerFactory = configBean.getUnmarshallerFactory();
        final Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(metadataRoot);
        if (unmarshaller == null) {
            throw new IllegalArgumentException("Unmarshaller for the metadata root element cannot be determined");
        }
        LOGGER.debug("Unmarshalling the document into a security token response");
        final RequestSecurityTokenResponse rsToken = (RequestSecurityTokenResponse) unmarshaller.unmarshall(metadataRoot);
        if (rsToken == null || rsToken.getRequestedSecurityToken() == null) {
            throw new IllegalArgumentException("Request security token response is null");
        }
        //Get our SAML token
        LOGGER.debug("Locating list of requested security tokens");
        final List<RequestedSecurityToken> rst = rsToken.getRequestedSecurityToken();
        if (rst.isEmpty()) {
            throw new IllegalArgumentException("No requested security token response is provided in the response");
        }
        LOGGER.debug("Locating the first occurrence of a requested security token in the list");
        final RequestedSecurityToken reqToken = rst.get(0);
        if (reqToken.getSecurityTokens() == null || reqToken.getSecurityTokens().isEmpty()) {
            throw new IllegalArgumentException("Requested security token response is not carrying any security tokens");
        }
        Assertion assertion = null;
        LOGGER.debug("Locating the first occurrence of a security token from the requested security token");
        XMLObject securityToken = reqToken.getSecurityTokens().get(0);
        if (securityToken instanceof EncryptedData) {
            try {
                LOGGER.debug("Security token is encrypted. Attempting to decrypt to extract the assertion");
                final EncryptedData encryptedData = EncryptedData.class.cast(securityToken);
                final Decrypter decrypter = buildAssertionDecrypter(config);
                LOGGER.debug("Built an instance of [{}]", decrypter.getClass().getName());
                securityToken = decrypter.decryptData(encryptedData);
            } catch (final Exception e) {
                throw new IllegalArgumentException("Unable to decrypt security token", e);
            }
        }
        if (securityToken instanceof Assertion) {
            LOGGER.debug("Security token is an assertion.");
            assertion = Assertion.class.cast(securityToken);
        }
        if (assertion == null) {
            throw new IllegalArgumentException("Could not extract or decrypt an assertion based on the security token provided");
        }
        LOGGER.debug("Extracted assertion successfully: [{}]", assertion);
        return assertion;
    } catch (final Exception ex) {
        LOGGER.warn(ex.getMessage());
        return null;
    }
}
Also used : RequestedSecurityToken(org.opensaml.soap.wsfed.RequestedSecurityToken) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Element(org.w3c.dom.Element) Assertion(org.opensaml.saml.saml1.core.Assertion) XMLObject(org.opensaml.core.xml.XMLObject) Decrypter(org.opensaml.saml.saml2.encryption.Decrypter) UnmarshallerFactory(org.opensaml.core.xml.io.UnmarshallerFactory) Document(org.w3c.dom.Document) SignatureException(org.opensaml.xmlsec.signature.support.SignatureException) SecurityException(org.opensaml.security.SecurityException) ByteArrayInputStream(java.io.ByteArrayInputStream) EncryptedData(org.opensaml.xmlsec.encryption.EncryptedData) Unmarshaller(org.opensaml.core.xml.io.Unmarshaller) RequestSecurityTokenResponse(org.opensaml.soap.wsfed.RequestSecurityTokenResponse)

Example 13 with Request

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

the class IdpEndpoint method determineAuthMethod.

private AuthObj determineAuthMethod(String bodyStr, AuthnRequest authnRequest) {
    XMLStreamReader xmlStreamReader = null;
    try {
        xmlStreamReader = xmlInputFactory.createXMLStreamReader(new StringReader(bodyStr));
    } catch (XMLStreamException e) {
        LOGGER.debug("Unable to parse SOAP message from client.", e);
    }
    SoapMessage soapMessage = new SoapMessage(Soap11.getInstance());
    SAAJInInterceptor.SAAJPreInInterceptor preInInterceptor = new SAAJInInterceptor.SAAJPreInInterceptor();
    soapMessage.setContent(XMLStreamReader.class, xmlStreamReader);
    preInInterceptor.handleMessage(soapMessage);
    SAAJInInterceptor inInterceptor = new SAAJInInterceptor();
    inInterceptor.handleMessage(soapMessage);
    SOAPPart soapMessageContent = (SOAPPart) soapMessage.getContent(Node.class);
    AuthObj authObj = new AuthObj();
    try {
        Iterator soapHeaderElements = soapMessageContent.getEnvelope().getHeader().examineAllHeaderElements();
        while (soapHeaderElements.hasNext()) {
            SOAPHeaderElement soapHeaderElement = (SOAPHeaderElement) soapHeaderElements.next();
            if (soapHeaderElement.getLocalName().equals("Security")) {
                Iterator childElements = soapHeaderElement.getChildElements();
                while (childElements.hasNext()) {
                    Object nextElement = childElements.next();
                    if (nextElement instanceof SOAPElement) {
                        SOAPElement element = (SOAPElement) nextElement;
                        if (element.getLocalName().equals("UsernameToken")) {
                            Iterator usernameTokenElements = element.getChildElements();
                            Object next;
                            while (usernameTokenElements.hasNext()) {
                                if ((next = usernameTokenElements.next()) instanceof Element) {
                                    Element nextEl = (Element) next;
                                    if (nextEl.getLocalName().equals("Username")) {
                                        authObj.username = nextEl.getTextContent();
                                    } else if (nextEl.getLocalName().equals("Password")) {
                                        authObj.password = nextEl.getTextContent();
                                    }
                                }
                            }
                            if (authObj.username != null && authObj.password != null) {
                                authObj.method = USER_PASS;
                                break;
                            }
                        } else if (element.getLocalName().equals("Assertion") && element.getNamespaceURI().equals("urn:oasis:names:tc:SAML:2.0:assertion")) {
                            authObj.assertion = new SecurityToken(element.getAttribute("ID"), element, null, null);
                            authObj.method = SAML;
                            break;
                        }
                    }
                }
            }
        }
    } catch (SOAPException e) {
        LOGGER.debug("Unable to parse SOAP message.", e);
    }
    RequestedAuthnContext requestedAuthnContext = authnRequest.getRequestedAuthnContext();
    boolean requestingPki = false;
    boolean requestingUp = false;
    if (requestedAuthnContext != null) {
        List<AuthnContextClassRef> authnContextClassRefs = requestedAuthnContext.getAuthnContextClassRefs();
        for (AuthnContextClassRef authnContextClassRef : authnContextClassRefs) {
            String authnContextClassRefStr = authnContextClassRef.getAuthnContextClassRef();
            if (SAML2Constants.AUTH_CONTEXT_CLASS_REF_X509.equals(authnContextClassRefStr) || SAML2Constants.AUTH_CONTEXT_CLASS_REF_SMARTCARD_PKI.equals(authnContextClassRefStr) || SAML2Constants.AUTH_CONTEXT_CLASS_REF_SOFTWARE_PKI.equals(authnContextClassRefStr) || SAML2Constants.AUTH_CONTEXT_CLASS_REF_SPKI.equals(authnContextClassRefStr) || SAML2Constants.AUTH_CONTEXT_CLASS_REF_TLS_CLIENT.equals(authnContextClassRefStr)) {
                requestingPki = true;
            } else if (SAML2Constants.AUTH_CONTEXT_CLASS_REF_PASSWORD.equals(authnContextClassRefStr) || SAML2Constants.AUTH_CONTEXT_CLASS_REF_PASSWORD_PROTECTED_TRANSPORT.equals(authnContextClassRefStr)) {
                requestingUp = true;
            }
        }
    } else {
        //The requested auth context isn't required so we don't know what they want... just set both to true
        requestingPki = true;
        requestingUp = true;
    }
    if (requestingUp && authObj.method != null && authObj.method.equals(USER_PASS)) {
        LOGGER.trace("Found UsernameToken and correct AuthnContextClassRef");
        return authObj;
    } else if (requestingPki && authObj.method == null) {
        LOGGER.trace("Found no token, but client requested PKI AuthnContextClassRef");
        authObj.method = PKI;
        return authObj;
    } else if (authObj.method == null) {
        LOGGER.debug("No authentication tokens found for the current request and the client did not request PKI authentication");
    }
    return authObj;
}
Also used : SOAPHeaderElement(javax.xml.soap.SOAPHeaderElement) XMLStreamReader(javax.xml.stream.XMLStreamReader) Node(org.w3c.dom.Node) SOAPElement(javax.xml.soap.SOAPElement) SOAPHeaderElement(javax.xml.soap.SOAPHeaderElement) Element(org.w3c.dom.Element) AuthnContextClassRef(org.opensaml.saml.saml2.core.AuthnContextClassRef) SoapMessage(org.apache.cxf.binding.soap.SoapMessage) SAAJInInterceptor(org.apache.cxf.binding.soap.saaj.SAAJInInterceptor) SecurityToken(org.apache.cxf.ws.security.tokenstore.SecurityToken) RequestedAuthnContext(org.opensaml.saml.saml2.core.RequestedAuthnContext) XMLStreamException(javax.xml.stream.XMLStreamException) SOAPException(javax.xml.soap.SOAPException) StringReader(java.io.StringReader) SOAPPart(javax.xml.soap.SOAPPart) Iterator(java.util.Iterator) SOAPElement(javax.xml.soap.SOAPElement) SignableSAMLObject(org.opensaml.saml.common.SignableSAMLObject) SignableXMLObject(org.opensaml.xmlsec.signature.SignableXMLObject) XMLObject(org.opensaml.core.xml.XMLObject)

Example 14 with Request

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

the class IdpEndpoint method processPostLogout.

@Override
@POST
@Path("/logout")
public Response processPostLogout(@FormParam(SAML_REQ) final String samlRequest, @FormParam(SAML_RESPONSE) final String samlResponse, @FormParam(RELAY_STATE) final String relayState, @Context final HttpServletRequest request) throws WSSecurityException, IdpException {
    LogoutState logoutState = getLogoutState(request);
    Cookie cookie = getCookie(request);
    try {
        if (samlRequest != null) {
            LogoutRequest logoutRequest = logoutMessage.extractSamlLogoutRequest(RestSecurity.inflateBase64(samlRequest));
            validatePost(request, logoutRequest);
            return handleLogoutRequest(cookie, logoutState, logoutRequest, SamlProtocol.Binding.HTTP_POST, relayState);
        } else if (samlResponse != null) {
            LogoutResponse logoutResponse = logoutMessage.extractSamlLogoutResponse(RestSecurity.inflateBase64(samlResponse));
            String requestId = logoutState != null ? logoutState.getCurrentRequestId() : null;
            validatePost(request, logoutResponse, requestId);
            return handleLogoutResponse(cookie, logoutState, logoutResponse, SamlProtocol.Binding.HTTP_POST);
        }
    } catch (IOException | XMLStreamException e) {
        throw new IdpException("Unable to inflate Saml Object", e);
    } catch (ValidationException e) {
        throw new IdpException("Unable to validate Saml Object", e);
    }
    throw new IdpException("Unable to process logout");
}
Also used : NewCookie(javax.ws.rs.core.NewCookie) Cookie(javax.servlet.http.Cookie) ValidationException(ddf.security.samlp.ValidationException) LogoutResponse(org.opensaml.saml.saml2.core.LogoutResponse) XMLStreamException(javax.xml.stream.XMLStreamException) LogoutRequest(org.opensaml.saml.saml2.core.LogoutRequest) IOException(java.io.IOException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Example 15 with Request

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

the class IdpEndpoint method doSoapLogin.

@POST
@Path("/login")
@Consumes({ "text/xml", "application/soap+xml" })
public Response doSoapLogin(InputStream body, @Context HttpServletRequest request) {
    if (!request.isSecure()) {
        throw new IllegalArgumentException("Authn Request must use TLS.");
    }
    SoapBinding soapBinding = new SoapBinding(systemCrypto, serviceProviders);
    try {
        String bodyStr = IOUtils.toString(body);
        AuthnRequest authnRequest = soapBinding.decoder().decodeRequest(bodyStr);
        String relayState = ((SoapRequestDecoder) soapBinding.decoder()).decodeRelayState(bodyStr);
        soapBinding.validator().validateRelayState(relayState);
        soapBinding.validator().validateAuthnRequest(authnRequest, bodyStr, null, null, null, strictSignature);
        boolean hasCookie = hasValidCookie(request, authnRequest.isForceAuthn());
        AuthObj authObj = determineAuthMethod(bodyStr, authnRequest);
        org.opensaml.saml.saml2.core.Response response = handleLogin(authnRequest, authObj.method, request, authObj, authnRequest.isPassive(), hasCookie);
        Response samlpResponse = soapBinding.creator().getSamlpResponse(relayState, authnRequest, response, null, soapMessage);
        samlpResponse.getHeaders().put("SOAPAction", Collections.singletonList("http://www.oasis-open.org/committees/security"));
        return samlpResponse;
    } catch (IOException e) {
        LOGGER.debug("Unable to decode SOAP AuthN Request", e);
    } catch (SimpleSign.SignatureException e) {
        LOGGER.debug("Unable to validate signature.", e);
    } catch (ValidationException e) {
        LOGGER.debug("Unable to validate request.", e);
    } catch (SecurityServiceException e) {
        LOGGER.debug("Unable to authenticate user.", e);
    } catch (WSSecurityException | IllegalArgumentException e) {
        LOGGER.debug("Bad request.", e);
    }
    return null;
}
Also used : SecurityServiceException(ddf.security.service.SecurityServiceException) ValidationException(ddf.security.samlp.ValidationException) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) SoapRequestDecoder(org.codice.ddf.security.idp.binding.soap.SoapRequestDecoder) IOException(java.io.IOException) SoapBinding(org.codice.ddf.security.idp.binding.soap.SoapBinding) LogoutResponse(org.opensaml.saml.saml2.core.LogoutResponse) Response(javax.ws.rs.core.Response) SimpleSign(ddf.security.samlp.SimpleSign) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes)

Aggregations

AuthnRequest (org.opensaml.saml.saml2.core.AuthnRequest)16 IOException (java.io.IOException)13 LogoutResponse (org.opensaml.saml.saml2.core.LogoutResponse)13 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)12 ValidationException (ddf.security.samlp.ValidationException)9 Response (javax.ws.rs.core.Response)9 Document (org.w3c.dom.Document)9 XMLStreamException (javax.xml.stream.XMLStreamException)8 LogoutRequest (org.opensaml.saml.saml2.core.LogoutRequest)7 ByteArrayInputStream (java.io.ByteArrayInputStream)6 Test (org.junit.Test)6 Matchers.anyString (org.mockito.Matchers.anyString)6 Assertion (org.opensaml.saml.saml2.core.Assertion)6 Element (org.w3c.dom.Element)6 SimpleSign (ddf.security.samlp.SimpleSign)5 Path (javax.ws.rs.Path)5 NewCookie (javax.ws.rs.core.NewCookie)5 XMLObject (org.opensaml.core.xml.XMLObject)5 MessageContext (org.opensaml.messaging.context.MessageContext)5 ServletException (javax.servlet.ServletException)4