Search in sources :

Example 6 with StatusResponseType

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

the class SamlService method artifactResolve.

/**
 * Takes an artifact resolve message and returns the artifact response, if the artifact is found belonging to a session
 * of the issuer.
 * @param artifactResolveMessage The artifact resolve message sent by the client
 * @param artifactResolveHolder the document containing the artifact resolve message sent by the client
 * @return a Response containing the SOAP message with the ArifactResponse
 * @throws ParsingException
 * @throws ConfigurationException
 * @throws ProcessingException
 */
public Response artifactResolve(ArtifactResolveType artifactResolveMessage, SAMLDocumentHolder artifactResolveHolder) throws ParsingException, ConfigurationException, ProcessingException {
    logger.debug("Received artifactResolve message for artifact " + artifactResolveMessage.getArtifact() + "\n" + "Message: \n" + DocumentUtil.getDocumentAsString(artifactResolveHolder.getSamlDocument()));
    // Artifact from resolve request
    String artifact = artifactResolveMessage.getArtifact();
    if (artifact == null) {
        logger.errorf("Artifact to resolve was null");
        return emptyArtifactResponseMessage(artifactResolveMessage, null, JBossSAMLURIConstants.STATUS_REQUEST_DENIED.getUri());
    }
    ArtifactResolver artifactResolver = getArtifactResolver(artifact);
    if (artifactResolver == null) {
        logger.errorf("Cannot find ArtifactResolver for artifact %s", artifact);
        return emptyArtifactResponseMessage(artifactResolveMessage, null, JBossSAMLURIConstants.STATUS_REQUEST_DENIED.getUri());
    }
    // Obtain details of session that issued artifact and check if it corresponds to issuer of Resolve message
    SamlArtifactSessionMappingModel sessionMapping = getArtifactSessionMappingStore().get(artifact);
    if (sessionMapping == null) {
        logger.errorf("No data stored for artifact %s", artifact);
        return emptyArtifactResponseMessage(artifactResolveMessage, null);
    }
    UserSessionModel userSessionModel = session.sessions().getUserSession(realm, sessionMapping.getUserSessionId());
    if (userSessionModel == null) {
        logger.errorf("UserSession with id: %s, that corresponds to artifact: %s does not exist.", sessionMapping.getUserSessionId(), artifact);
        return emptyArtifactResponseMessage(artifactResolveMessage, null);
    }
    AuthenticatedClientSessionModel clientSessionModel = userSessionModel.getAuthenticatedClientSessions().get(sessionMapping.getClientSessionId());
    if (clientSessionModel == null) {
        logger.errorf("ClientSession with id: %s, that corresponds to artifact: %s and UserSession: %s does not exist.", sessionMapping.getClientSessionId(), artifact, sessionMapping.getUserSessionId());
        return emptyArtifactResponseMessage(artifactResolveMessage, null);
    }
    ClientModel clientModel = getAndCheckClientModel(sessionMapping.getClientSessionId(), artifactResolveMessage.getIssuer().getValue());
    SamlClient samlClient = new SamlClient(clientModel);
    // Check signature within ArtifactResolve request if client requires it
    if (samlClient.requiresClientSignature()) {
        try {
            SamlProtocolUtils.verifyDocumentSignature(clientModel, artifactResolveHolder.getSamlDocument());
        } catch (VerificationException e) {
            SamlService.logger.error("request validation failed", e);
            return emptyArtifactResponseMessage(artifactResolveMessage, clientModel);
        }
    }
    // Obtain artifactResponse from clientSessionModel
    String artifactResponseString;
    try {
        artifactResponseString = artifactResolver.resolveArtifact(clientSessionModel, artifact);
    } catch (ArtifactResolverProcessingException e) {
        logger.errorf(e, "Failed to resolve artifact: %s.", artifact);
        return emptyArtifactResponseMessage(artifactResolveMessage, clientModel);
    }
    // Artifact is successfully resolved, we can remove session mapping from storage
    getArtifactSessionMappingStore().remove(artifact);
    Document artifactResponseDocument = null;
    ArtifactResponseType artifactResponseType = null;
    try {
        SAMLDataMarshaller marshaller = new SAMLDataMarshaller();
        artifactResponseType = marshaller.deserialize(artifactResponseString, ArtifactResponseType.class);
        artifactResponseDocument = SamlProtocolUtils.convert(artifactResponseType);
    } catch (ParsingException | ConfigurationException | ProcessingException e) {
        logger.errorf(e, "Failed to obtain document from ArtifactResponseString: %s.", artifactResponseString);
        return emptyArtifactResponseMessage(artifactResolveMessage, clientModel);
    }
    // If clientSession is in LOGGING_OUT action, now we can move it to LOGGED_OUT
    if (CommonClientSessionModel.Action.LOGGING_OUT.name().equals(clientSessionModel.getAction())) {
        clientSessionModel.setAction(CommonClientSessionModel.Action.LOGGED_OUT.name());
        // If Keycloak sent LogoutResponse we need to also remove UserSession
        if (artifactResponseType.getAny() instanceof StatusResponseType && artifactResponseString.contains(JBossSAMLConstants.LOGOUT_RESPONSE.get())) {
            if (!UserSessionModel.State.LOGGED_OUT_UNCONFIRMED.equals(userSessionModel.getState())) {
                logger.warnf("Keycloak issued LogoutResponse for clientSession %s, however user session %s was not in LOGGED_OUT_UNCONFIRMED state.", clientSessionModel.getId(), userSessionModel.getId());
            }
            AuthenticationManager.finishUnconfirmedUserSession(session, realm, userSessionModel);
        }
    }
    return artifactResponseMessage(artifactResolveMessage, artifactResponseDocument, clientModel);
}
Also used : UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) Document(org.w3c.dom.Document) SAMLDataMarshaller(org.keycloak.broker.saml.SAMLDataMarshaller) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) SamlArtifactSessionMappingModel(org.keycloak.models.SamlArtifactSessionMappingModel) ClientModel(org.keycloak.models.ClientModel) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) ParsingException(org.keycloak.saml.common.exceptions.ParsingException) VerificationException(org.keycloak.common.VerificationException) ArtifactResponseType(org.keycloak.dom.saml.v2.protocol.ArtifactResponseType) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException)

Example 7 with StatusResponseType

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

the class SAML2LogoutResponseBuilder method buildDocument.

public Document buildDocument() throws ProcessingException {
    Document samlResponse = null;
    try {
        StatusResponseType statusResponse = buildModel();
        SAML2Response saml2Response = new SAML2Response();
        samlResponse = saml2Response.convert(statusResponse);
    } catch (ConfigurationException e) {
        throw new ProcessingException(e);
    } catch (ParsingException e) {
        throw new ProcessingException(e);
    }
    return samlResponse;
}
Also used : ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) ParsingException(org.keycloak.saml.common.exceptions.ParsingException) SAML2Response(org.keycloak.saml.processing.api.saml.v2.response.SAML2Response) Document(org.w3c.dom.Document) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException)

Example 8 with StatusResponseType

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

the class SAML2ErrorResponseBuilder method buildDocument.

public Document buildDocument() throws ProcessingException {
    try {
        StatusResponseType statusResponse = new ResponseType(IDGenerator.create("ID_"), XMLTimeUtil.getIssueInstant());
        statusResponse.setStatus(JBossSAMLAuthnResponseFactory.createStatusTypeForResponder(status));
        statusResponse.setIssuer(issuer);
        statusResponse.setDestination(destination);
        if (!this.extensions.isEmpty()) {
            ExtensionsType extensionsType = new ExtensionsType();
            for (NodeGenerator extension : this.extensions) {
                extensionsType.addExtension(extension);
            }
            statusResponse.setExtensions(extensionsType);
        }
        SAML2Response saml2Response = new SAML2Response();
        return saml2Response.convert(statusResponse);
    } catch (ConfigurationException e) {
        throw new ProcessingException(e);
    } catch (ParsingException e) {
        throw new ProcessingException(e);
    }
}
Also used : ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) ExtensionsType(org.keycloak.dom.saml.v2.protocol.ExtensionsType) ParsingException(org.keycloak.saml.common.exceptions.ParsingException) SAML2Response(org.keycloak.saml.processing.api.saml.v2.response.SAML2Response) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException)

Example 9 with StatusResponseType

use of org.keycloak.dom.saml.v2.protocol.StatusResponseType 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 10 with StatusResponseType

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

the class SamlDocumentStepBuilder method saml2Object2String.

public static String saml2Object2String(final SAML2Object transformed) {
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        XMLStreamWriter xmlStreamWriter = StaxUtil.getXMLStreamWriter(bos);
        if (transformed instanceof AuthnRequestType) {
            new SAMLRequestWriter(xmlStreamWriter).write((AuthnRequestType) transformed);
        } else if (transformed instanceof LogoutRequestType) {
            new SAMLRequestWriter(xmlStreamWriter).write((LogoutRequestType) transformed);
        } else if (transformed instanceof ArtifactResolveType) {
            new SAMLRequestWriter(xmlStreamWriter).write((ArtifactResolveType) transformed);
        } else if (transformed instanceof AttributeQueryType) {
            new SAMLRequestWriter(xmlStreamWriter).write((AttributeQueryType) transformed);
        } else if (transformed instanceof ResponseType) {
            new SAMLResponseWriter(xmlStreamWriter).write((ResponseType) transformed);
        } else if (transformed instanceof ArtifactResponseType) {
            new SAMLResponseWriter(xmlStreamWriter).write((ArtifactResponseType) transformed);
        } else if (transformed instanceof StatusResponseType) {
            new SAMLResponseWriter(xmlStreamWriter).write((StatusResponseType) transformed, SAMLProtocolQNames.LOGOUT_RESPONSE.getQName("samlp"));
        } else {
            Assert.assertNotNull("Unknown type: <null>", transformed);
            Assert.fail("Unknown type: " + transformed.getClass().getName());
        }
        return new String(bos.toByteArray(), GeneralConstants.SAML_CHARSET);
    } catch (ProcessingException ex) {
        throw new RuntimeException(ex);
    }
}
Also used : ArtifactResolveType(org.keycloak.dom.saml.v2.protocol.ArtifactResolveType) LogoutRequestType(org.keycloak.dom.saml.v2.protocol.LogoutRequestType) ByteArrayOutputStream(java.io.ByteArrayOutputStream) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) ArtifactResponseType(org.keycloak.dom.saml.v2.protocol.ArtifactResponseType) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) SAMLResponseWriter(org.keycloak.saml.processing.core.saml.v2.writers.SAMLResponseWriter) AuthnRequestType(org.keycloak.dom.saml.v2.protocol.AuthnRequestType) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) SAMLRequestWriter(org.keycloak.saml.processing.core.saml.v2.writers.SAMLRequestWriter) ArtifactResponseType(org.keycloak.dom.saml.v2.protocol.ArtifactResponseType) AttributeQueryType(org.keycloak.dom.saml.v2.protocol.AttributeQueryType) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException)

Aggregations

StatusResponseType (org.keycloak.dom.saml.v2.protocol.StatusResponseType)22 Test (org.junit.Test)13 SAMLDocumentHolder (org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder)9 SamlClientBuilder (org.keycloak.testsuite.util.SamlClientBuilder)7 ArtifactResponseType (org.keycloak.dom.saml.v2.protocol.ArtifactResponseType)6 ResponseType (org.keycloak.dom.saml.v2.protocol.ResponseType)6 ProcessingException (org.keycloak.saml.common.exceptions.ProcessingException)5 QName (javax.xml.namespace.QName)4 SAML2Object (org.keycloak.dom.saml.v2.SAML2Object)4 ExtensionsType (org.keycloak.dom.saml.v2.protocol.ExtensionsType)4 LogoutRequestType (org.keycloak.dom.saml.v2.protocol.LogoutRequestType)4 ParsingException (org.keycloak.saml.common.exceptions.ParsingException)4 Document (org.w3c.dom.Document)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3 Response (javax.ws.rs.core.Response)3 StatusCodeType (org.keycloak.dom.saml.v2.protocol.StatusCodeType)3 StatusType (org.keycloak.dom.saml.v2.protocol.StatusType)3 UserSessionModel (org.keycloak.models.UserSessionModel)3 ConfigurationException (org.keycloak.saml.common.exceptions.ConfigurationException)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2