Search in sources :

Example 1 with SAMLDataMarshaller

use of org.keycloak.broker.saml.SAMLDataMarshaller in project keycloak by keycloak.

the class SAMLDataMarshallerTest method testParseAssertionWitNameId.

@Test
public void testParseAssertionWitNameId() {
    SAMLDataMarshaller serializer = new SAMLDataMarshaller();
    AssertionType assertion = serializer.deserialize(TEST_ASSERTION_WITH_NAME_ID, AssertionType.class);
    // test assertion
    Assert.assertEquals("ID_29b196c2-d641-45c8-a423-8ed8e54d4cf9", assertion.getID());
    Assert.assertEquals("test-user", ((NameIDType) assertion.getSubject().getSubType().getBaseID()).getValue());
    // back to String
    String serialized = serializer.serialize(assertion);
    Assert.assertEquals(TEST_ASSERTION_WITH_NAME_ID, serialized);
}
Also used : AssertionType(org.keycloak.dom.saml.v2.assertion.AssertionType) SAMLDataMarshaller(org.keycloak.broker.saml.SAMLDataMarshaller) Test(org.junit.Test)

Example 2 with SAMLDataMarshaller

use of org.keycloak.broker.saml.SAMLDataMarshaller in project keycloak by keycloak.

the class SAMLDataMarshallerTest method testSerializeWithNamespaceInSignatureElement.

@Test
public void testSerializeWithNamespaceInSignatureElement() throws Exception {
    SAMLParser parser = SAMLParser.getInstance();
    try (InputStream st = SAMLDataMarshallerTest.class.getResourceAsStream("saml-response-ds-ns-in-signature.xml")) {
        Object parsedObject = parser.parse(st);
        assertThat(parsedObject, instanceOf(ResponseType.class));
        ResponseType response = (ResponseType) parsedObject;
        SAMLDataMarshaller serializer = new SAMLDataMarshaller();
        String serialized = serializer.serialize(response.getAssertions().get(0).getAssertion());
        AssertionType deserialized = serializer.deserialize(serialized, AssertionType.class);
        assertThat(deserialized, CoreMatchers.notNullValue());
        assertThat(deserialized.getID(), CoreMatchers.is("id-4r-Xj702KQsM0gJyu3Fqpuwfe-LvDrEcQZpxKrhC"));
    }
}
Also used : InputStream(java.io.InputStream) SAMLParser(org.keycloak.saml.processing.core.parsers.saml.SAMLParser) AssertionType(org.keycloak.dom.saml.v2.assertion.AssertionType) SAMLDataMarshaller(org.keycloak.broker.saml.SAMLDataMarshaller) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) Test(org.junit.Test)

Example 3 with SAMLDataMarshaller

use of org.keycloak.broker.saml.SAMLDataMarshaller in project keycloak by keycloak.

the class SAMLDataMarshallerTest method testParseAssertion.

@Test
public void testParseAssertion() {
    SAMLDataMarshaller serializer = new SAMLDataMarshaller();
    AssertionType assertion = serializer.deserialize(TEST_ASSERTION, AssertionType.class);
    // test assertion
    Assert.assertEquals("ID_29b196c2-d641-45c8-a423-8ed8e54d4cf9", assertion.getID());
    Assert.assertEquals("test-user", ((NameIDType) assertion.getSubject().getSubType().getBaseID()).getValue());
    // back to String
    String serialized = serializer.serialize(assertion);
    Assert.assertEquals(TEST_ASSERTION, serialized);
}
Also used : AssertionType(org.keycloak.dom.saml.v2.assertion.AssertionType) SAMLDataMarshaller(org.keycloak.broker.saml.SAMLDataMarshaller) Test(org.junit.Test)

Example 4 with SAMLDataMarshaller

use of org.keycloak.broker.saml.SAMLDataMarshaller 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 5 with SAMLDataMarshaller

use of org.keycloak.broker.saml.SAMLDataMarshaller in project keycloak by keycloak.

the class SAMLDataMarshallerTest method testParseResponse.

@Test
public void testParseResponse() {
    SAMLDataMarshaller serializer = new SAMLDataMarshaller();
    ResponseType responseType = serializer.deserialize(TEST_RESPONSE, ResponseType.class);
    // test ResponseType
    Assert.assertEquals("ID_4804cf50-cd96-4b92-823e-89adaa0c78ba", responseType.getID());
    Assert.assertEquals("http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint", responseType.getDestination());
    Assert.assertEquals("http://localhost:8082/auth/realms/realm-with-saml-idp-basic", responseType.getIssuer().getValue());
    Assert.assertEquals("ID_29b196c2-d641-45c8-a423-8ed8e54d4cf9", responseType.getAssertions().get(0).getID());
    // back to String
    String serialized = serializer.serialize(responseType);
    Assert.assertEquals(TEST_RESPONSE, serialized);
}
Also used : SAMLDataMarshaller(org.keycloak.broker.saml.SAMLDataMarshaller) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) Test(org.junit.Test)

Aggregations

SAMLDataMarshaller (org.keycloak.broker.saml.SAMLDataMarshaller)8 Test (org.junit.Test)6 AssertionType (org.keycloak.dom.saml.v2.assertion.AssertionType)4 ResponseType (org.keycloak.dom.saml.v2.protocol.ResponseType)3 InputStream (java.io.InputStream)2 ArtifactResponseType (org.keycloak.dom.saml.v2.protocol.ArtifactResponseType)2 SAMLParser (org.keycloak.saml.processing.core.parsers.saml.SAMLParser)2 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)1 VerificationException (org.keycloak.common.VerificationException)1 AuthnStatementType (org.keycloak.dom.saml.v2.assertion.AuthnStatementType)1 StatusResponseType (org.keycloak.dom.saml.v2.protocol.StatusResponseType)1 AuthenticatedClientSessionModel (org.keycloak.models.AuthenticatedClientSessionModel)1 ClientModel (org.keycloak.models.ClientModel)1 SamlArtifactSessionMappingModel (org.keycloak.models.SamlArtifactSessionMappingModel)1 UserSessionModel (org.keycloak.models.UserSessionModel)1 ConfigurationException (org.keycloak.saml.common.exceptions.ConfigurationException)1 ParsingException (org.keycloak.saml.common.exceptions.ParsingException)1 ProcessingException (org.keycloak.saml.common.exceptions.ProcessingException)1 Document (org.w3c.dom.Document)1