Search in sources :

Example 1 with StatusType

use of org.keycloak.dom.saml.v2.protocol.StatusType in project keycloak by keycloak.

the class SAMLStatusParser method processSubElement.

@Override
protected void processSubElement(XMLEventReader xmlEventReader, StatusType target, SAMLProtocolQNames element, StartElement elementDetail) throws ParsingException {
    switch(element) {
        case STATUS_CODE:
            target.setStatusCode(SAMLStatusCodeParser.getInstance().parse(xmlEventReader));
            break;
        case STATUS_MESSAGE:
            StaxParserUtil.advance(xmlEventReader);
            target.setStatusMessage(StaxParserUtil.getElementText(xmlEventReader));
            break;
        case STATUS_DETAIL:
            List<Element> elements = STATUS_DETAIL_PARSER.parse(xmlEventReader);
            StatusDetailType statusDetailType = new StatusDetailType();
            for (Element e : elements) {
                statusDetailType.addStatusDetail(e);
            }
            target.setStatusDetail(statusDetailType);
            break;
        default:
            throw LOGGER.parserUnknownTag(StaxParserUtil.getElementName(elementDetail), elementDetail.getLocation());
    }
}
Also used : StatusDetailType(org.keycloak.dom.saml.v2.protocol.StatusDetailType) Element(org.w3c.dom.Element) StartElement(javax.xml.stream.events.StartElement)

Example 2 with StatusType

use of org.keycloak.dom.saml.v2.protocol.StatusType in project keycloak by keycloak.

the class SAMLResponseWriter method write.

/**
 * Write a {@code StatusType} to stream
 *
 * @param status
 * @param out
 *
 * @throws ProcessingException
 */
public void write(StatusType status) throws ProcessingException {
    StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.STATUS.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
    StatusCodeType statusCodeType = status.getStatusCode();
    write(statusCodeType);
    String statusMessage = status.getStatusMessage();
    if (StringUtil.isNotNull(statusMessage)) {
        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.STATUS_MESSAGE.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
        StaxUtil.writeEndElement(writer);
    }
    StatusDetailType statusDetail = status.getStatusDetail();
    if (statusDetail != null)
        write(statusDetail);
    StaxUtil.writeEndElement(writer);
    StaxUtil.flush(writer);
}
Also used : StatusDetailType(org.keycloak.dom.saml.v2.protocol.StatusDetailType) StatusCodeType(org.keycloak.dom.saml.v2.protocol.StatusCodeType)

Example 3 with StatusType

use of org.keycloak.dom.saml.v2.protocol.StatusType in project keycloak by keycloak.

the class SAMLResponseWriter method write.

public void write(ArtifactResponseType response) throws ProcessingException {
    StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.ARTIFACT_RESPONSE.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
    StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, JBossSAMLURIConstants.PROTOCOL_NSURI.get());
    StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, JBossSAMLURIConstants.ASSERTION_NSURI.get());
    StaxUtil.writeDefaultNameSpace(writer, JBossSAMLURIConstants.ASSERTION_NSURI.get());
    writeBaseAttributes(response);
    NameIDType issuer = response.getIssuer();
    if (issuer != null) {
        write(issuer, new QName(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
    }
    Element sig = response.getSignature();
    if (sig != null) {
        StaxUtil.writeDOMElement(writer, sig);
    }
    ExtensionsType extensions = response.getExtensions();
    if (extensions != null && extensions.getAny() != null && !extensions.getAny().isEmpty()) {
        write(extensions);
    }
    StatusType status = response.getStatus();
    if (status != null) {
        write(status);
    }
    Object anyObj = response.getAny();
    if (anyObj instanceof AuthnRequestType) {
        AuthnRequestType authn = (AuthnRequestType) anyObj;
        SAMLRequestWriter requestWriter = new SAMLRequestWriter(writer);
        requestWriter.write(authn);
    } else if (anyObj instanceof LogoutRequestType) {
        LogoutRequestType logoutRequestType = (LogoutRequestType) anyObj;
        SAMLRequestWriter requestWriter = new SAMLRequestWriter(writer);
        requestWriter.write(logoutRequestType);
    } else if (anyObj instanceof ResponseType) {
        ResponseType rt = (ResponseType) anyObj;
        write(rt);
    } else if (anyObj instanceof StatusResponseType) {
        StatusResponseType rt = (StatusResponseType) anyObj;
        write(rt, new QName(PROTOCOL_NSURI.get(), JBossSAMLConstants.LOGOUT_RESPONSE.get(), "samlp"));
    }
    StaxUtil.writeEndElement(writer);
    StaxUtil.flush(writer);
}
Also used : AuthnRequestType(org.keycloak.dom.saml.v2.protocol.AuthnRequestType) QName(javax.xml.namespace.QName) StatusType(org.keycloak.dom.saml.v2.protocol.StatusType) Element(org.w3c.dom.Element) ExtensionsType(org.keycloak.dom.saml.v2.protocol.ExtensionsType) LogoutRequestType(org.keycloak.dom.saml.v2.protocol.LogoutRequestType) NameIDType(org.keycloak.dom.saml.v2.assertion.NameIDType) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) ArtifactResponseType(org.keycloak.dom.saml.v2.protocol.ArtifactResponseType) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType)

Example 4 with StatusType

use of org.keycloak.dom.saml.v2.protocol.StatusType in project keycloak by keycloak.

the class SAMLResponseWriter method write.

/**
 * Write a {@code ResponseType} to stream
 *
 * @param response
 * @param out
 *
 * @throws org.keycloak.saml.common.exceptions.ProcessingException
 */
public void write(ResponseType response) throws ProcessingException {
    StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.RESPONSE__PROTOCOL.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
    StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, JBossSAMLURIConstants.PROTOCOL_NSURI.get());
    StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, JBossSAMLURIConstants.ASSERTION_NSURI.get());
    writeBaseAttributes(response);
    NameIDType issuer = response.getIssuer();
    if (issuer != null) {
        write(issuer, new QName(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
    }
    ExtensionsType extensions = response.getExtensions();
    if (extensions != null && extensions.getAny() != null && !extensions.getAny().isEmpty()) {
        write(extensions);
    }
    StatusType status = response.getStatus();
    write(status);
    List<ResponseType.RTChoiceType> choiceTypes = response.getAssertions();
    if (choiceTypes != null) {
        for (ResponseType.RTChoiceType choiceType : choiceTypes) {
            AssertionType assertion = choiceType.getAssertion();
            if (assertion != null) {
                assertionWriter.write(assertion);
            }
            EncryptedAssertionType encryptedAssertion = choiceType.getEncryptedAssertion();
            if (encryptedAssertion != null) {
                Element encElement = encryptedAssertion.getEncryptedElement();
                StaxUtil.writeDOMElement(writer, encElement);
            }
        }
    }
    StaxUtil.writeEndElement(writer);
    StaxUtil.flush(writer);
}
Also used : QName(javax.xml.namespace.QName) StatusType(org.keycloak.dom.saml.v2.protocol.StatusType) ExtensionsType(org.keycloak.dom.saml.v2.protocol.ExtensionsType) Element(org.w3c.dom.Element) EncryptedAssertionType(org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType) AssertionType(org.keycloak.dom.saml.v2.assertion.AssertionType) EncryptedAssertionType(org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType) NameIDType(org.keycloak.dom.saml.v2.assertion.NameIDType) ArtifactResponseType(org.keycloak.dom.saml.v2.protocol.ArtifactResponseType) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType)

Example 5 with StatusType

use of org.keycloak.dom.saml.v2.protocol.StatusType in project keycloak by keycloak.

the class AbstractSamlAuthenticationHandler method handleSamlResponse.

protected AuthOutcome handleSamlResponse(String samlResponse, String relayState, OnSessionCreated onCreateSession) {
    SAMLDocumentHolder holder = null;
    boolean postBinding = false;
    String requestUri = facade.getRequest().getURI();
    if (facade.getRequest().getMethod().equalsIgnoreCase("GET")) {
        int index = requestUri.indexOf('?');
        if (index > -1) {
            requestUri = requestUri.substring(0, index);
        }
        holder = extractRedirectBindingResponse(samlResponse);
    } else {
        postBinding = true;
        holder = extractPostBindingResponse(samlResponse);
    }
    if (holder == null) {
        log.error("Error parsing SAML document");
        return failed(CHALLENGE_EXTRACTION_FAILURE);
    }
    final StatusResponseType statusResponse = (StatusResponseType) holder.getSamlObject();
    // validate destination
    if (statusResponse.getDestination() == null && containsUnencryptedSignature(holder, postBinding)) {
        log.error("Destination field required.");
        return failed(CHALLENGE_EXTRACTION_FAILURE);
    }
    if (!destinationValidator.validate(requestUri, statusResponse.getDestination())) {
        log.error("Request URI '" + requestUri + "' does not match SAML request destination '" + statusResponse.getDestination() + "'");
        return failedTerminal();
    }
    if (statusResponse instanceof ResponseType) {
        try {
            if (deployment.getIDP().getSingleSignOnService().validateResponseSignature()) {
                try {
                    validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
                } catch (VerificationException e) {
                    log.error("Failed to verify saml response signature", e);
                    return failed(CHALLENGE_INVALID_SIGNATURE);
                }
            }
            return handleLoginResponse(holder, postBinding, onCreateSession);
        } finally {
            sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
        }
    } else {
        if (sessionStore.isLoggingOut()) {
            try {
                if (deployment.getIDP().getSingleLogoutService().validateResponseSignature()) {
                    try {
                        validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
                    } catch (VerificationException e) {
                        log.error("Failed to verify saml response signature", e);
                        return failedTerminal();
                    }
                }
                return handleLogoutResponse(holder, statusResponse, relayState);
            } finally {
                sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
            }
        } else if (sessionStore.isLoggingIn()) {
            try {
                // KEYCLOAK-2107 - handle user not authenticated due passive mode. Return special outcome so different authentication mechanisms can behave accordingly.
                StatusType status = statusResponse.getStatus();
                if (checkStatusCodeValue(status.getStatusCode(), JBossSAMLURIConstants.STATUS_RESPONDER.get()) && checkStatusCodeValue(status.getStatusCode().getStatusCode(), JBossSAMLURIConstants.STATUS_NO_PASSIVE.get())) {
                    log.debug("Not authenticated due passive mode Status found in SAML response: " + status.toString());
                    return AuthOutcome.NOT_AUTHENTICATED;
                }
                return failed(createAuthChallenge403(statusResponse));
            } finally {
                sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
            }
        }
        log.warn("Keycloak Adapter obtained Response, that is not understood. This may be because the containers " + "cookies are not properly configured with SameSite settings. Refer to KEYCLOAK-14103 for more details.");
        return AuthOutcome.NOT_ATTEMPTED;
    }
}
Also used : SAMLDocumentHolder(org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder) StatusType(org.keycloak.dom.saml.v2.protocol.StatusType) VerificationException(org.keycloak.common.VerificationException) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType)

Aggregations

StatusType (org.keycloak.dom.saml.v2.protocol.StatusType)8 StatusCodeType (org.keycloak.dom.saml.v2.protocol.StatusCodeType)5 ExtensionsType (org.keycloak.dom.saml.v2.protocol.ExtensionsType)4 StatusResponseType (org.keycloak.dom.saml.v2.protocol.StatusResponseType)4 Element (org.w3c.dom.Element)4 QName (javax.xml.namespace.QName)3 NameIDType (org.keycloak.dom.saml.v2.assertion.NameIDType)3 ArtifactResponseType (org.keycloak.dom.saml.v2.protocol.ArtifactResponseType)3 ResponseType (org.keycloak.dom.saml.v2.protocol.ResponseType)3 StatusDetailType (org.keycloak.dom.saml.v2.protocol.StatusDetailType)2 StartElement (javax.xml.stream.events.StartElement)1 VerificationException (org.keycloak.common.VerificationException)1 AssertionType (org.keycloak.dom.saml.v2.assertion.AssertionType)1 EncryptedAssertionType (org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType)1 AuthnRequestType (org.keycloak.dom.saml.v2.protocol.AuthnRequestType)1 LogoutRequestType (org.keycloak.dom.saml.v2.protocol.LogoutRequestType)1 SAMLDocumentHolder (org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder)1