Search in sources :

Example 41 with SAMLDocumentHolder

use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder in project keycloak by keycloak.

the class LogoutTest method testFrontchannelLogoutDifferentBrowser.

@Test
public void testFrontchannelLogoutDifferentBrowser() {
    adminClient.realm(REALM_NAME).clients().get(sales2Rep.getId()).update(ClientBuilder.edit(sales2Rep).frontchannelLogout(true).attribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE, "").build());
    SAMLDocumentHolder samlResponse = prepareLogIntoTwoApps().clearCookies().logoutRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST, POST).nameId(nameIdRef::get).sessionIndex(sessionIndexRef::get).build().getSamlResponse(POST);
    assertThat(samlResponse.getSamlObject(), isSamlStatusResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
}
Also used : SAMLDocumentHolder(org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder) Test(org.junit.Test)

Example 42 with SAMLDocumentHolder

use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder 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)

Example 43 with SAMLDocumentHolder

use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder in project keycloak by keycloak.

the class AbstractSamlAuthenticationHandler method handleSamlRequest.

protected AuthOutcome handleSamlRequest(String samlRequest, String relayState) {
    SAMLDocumentHolder holder = null;
    boolean postBinding = false;
    String requestUri = facade.getRequest().getURI();
    if (facade.getRequest().getMethod().equalsIgnoreCase("GET")) {
        // strip out query params
        int index = requestUri.indexOf('?');
        if (index > -1) {
            requestUri = requestUri.substring(0, index);
        }
        holder = SAMLRequestParser.parseRequestRedirectBinding(samlRequest);
    } else {
        postBinding = true;
        holder = SAMLRequestParser.parseRequestPostBinding(samlRequest);
    }
    if (holder == null) {
        log.error("Error parsing SAML document");
        return failedTerminal();
    }
    RequestAbstractType requestAbstractType = (RequestAbstractType) holder.getSamlObject();
    if (requestAbstractType.getDestination() == null && containsUnencryptedSignature(holder, postBinding)) {
        log.error("Destination field required.");
        return failed(CHALLENGE_EXTRACTION_FAILURE);
    }
    if (!destinationValidator.validate(requestUri, requestAbstractType.getDestination())) {
        log.error("Expected destination '" + requestUri + "' got '" + requestAbstractType.getDestination() + "'");
        return failedTerminal();
    }
    if (requestAbstractType instanceof LogoutRequestType) {
        if (deployment.getIDP().getSingleLogoutService().validateRequestSignature()) {
            try {
                validateSamlSignature(holder, postBinding, GeneralConstants.SAML_REQUEST_KEY);
            } catch (VerificationException e) {
                log.error("Failed to verify saml request signature", e);
                return failedTerminal();
            }
        }
        LogoutRequestType logout = (LogoutRequestType) requestAbstractType;
        return logoutRequest(logout, relayState);
    } else {
        log.error("unknown SAML request type");
        return failedTerminal();
    }
}
Also used : SAMLDocumentHolder(org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder) RequestAbstractType(org.keycloak.dom.saml.v2.protocol.RequestAbstractType) LogoutRequestType(org.keycloak.dom.saml.v2.protocol.LogoutRequestType) VerificationException(org.keycloak.common.VerificationException)

Example 44 with SAMLDocumentHolder

use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder in project keycloak by keycloak.

the class KcSamlBrokerFrontendUrlTest method testFrontendUrlInDestinationExpected.

@Test
public void testFrontendUrlInDestinationExpected() throws URISyntaxException {
    SAMLDocumentHolder samlResponse = clientBuilderTrustingAllCertificates().idpInitiatedLogin(new URI(proxy.getUrl() + "/realms/" + bc.consumerRealmName() + "/protocol/saml"), "sales-post").build().login().idp(IDP_SAML_ALIAS).build().processSamlResponse(// AuthnRequest to producer IdP
    SamlClient.Binding.POST).targetAttributeSamlRequest().build().login().user(USER_LOGIN, USER_PASSWORD).build().processSamlResponse(SamlClient.Binding.POST).transformObject(saml2Object -> {
        assertThat(saml2Object, Matchers.isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
        ResponseType response = (ResponseType) saml2Object;
        assertThat(response.getDestination(), startsWith(proxy.getUrl()));
        return saml2Object;
    }).build().updateProfile().username(USER_LOGIN).email(USER_EMAIL).firstName("Firstname").lastName("Lastname").build().followOneRedirect().getSamlResponse(SamlClient.Binding.POST);
    assertThat(samlResponse.getSamlObject(), Matchers.isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
}
Also used : ReverseProxy(org.keycloak.testsuite.util.ReverseProxy) USER_PASSWORD(org.keycloak.testsuite.broker.BrokerTestConstants.USER_PASSWORD) IDP_SAML_ALIAS(org.keycloak.testsuite.broker.BrokerTestConstants.IDP_SAML_ALIAS) URISyntaxException(java.net.URISyntaxException) AssertEvents(org.keycloak.testsuite.AssertEvents) HashMap(java.util.HashMap) CoreMatchers.startsWith(org.hamcrest.CoreMatchers.startsWith) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) KeyStoreException(java.security.KeyStoreException) USER_EMAIL(org.keycloak.testsuite.broker.BrokerTestConstants.USER_EMAIL) ArrayList(java.util.ArrayList) BrokerTestTools.getConsumerRoot(org.keycloak.testsuite.broker.BrokerTestTools.getConsumerRoot) Map(java.util.Map) SamlClient(org.keycloak.testsuite.util.SamlClient) NoopHostnameVerifier(org.apache.http.conn.ssl.NoopHostnameVerifier) URI(java.net.URI) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) SAMLDocumentHolder(org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder) Errors(org.keycloak.events.Errors) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) Matchers(org.keycloak.testsuite.util.Matchers) JBossSAMLURIConstants(org.keycloak.saml.common.constants.JBossSAMLURIConstants) Test(org.junit.Test) EventType(org.keycloak.events.EventType) KeyManagementException(java.security.KeyManagementException) SSLContextBuilder(org.apache.http.ssl.SSLContextBuilder) RealmRepresentation(org.keycloak.representations.idm.RealmRepresentation) ClientRepresentation(org.keycloak.representations.idm.ClientRepresentation) URLEncoder(java.net.URLEncoder) List(java.util.List) Rule(org.junit.Rule) USER_LOGIN(org.keycloak.testsuite.broker.BrokerTestConstants.USER_LOGIN) Ignore(org.junit.Ignore) Response(javax.ws.rs.core.Response) REALM_CONS_NAME(org.keycloak.testsuite.broker.BrokerTestConstants.REALM_CONS_NAME) BrokerTestTools.waitForPage(org.keycloak.testsuite.broker.BrokerTestTools.waitForPage) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) HttpClientBuilder(org.apache.http.impl.client.HttpClientBuilder) UnsupportedEncodingException(java.io.UnsupportedEncodingException) TrustAllStrategy(org.apache.http.conn.ssl.TrustAllStrategy) SamlClientBuilder(org.keycloak.testsuite.util.SamlClientBuilder) SAMLDocumentHolder(org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder) URI(java.net.URI) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) Test(org.junit.Test)

Example 45 with SAMLDocumentHolder

use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder in project keycloak by keycloak.

the class SAML2Request method getAuthnRequestType.

/**
 * Get the AuthnRequestType from an input stream
 *
 * @param is Inputstream containing the AuthnRequest
 *
 * @return
 *
 * @throws ParsingException
 * @throws ProcessingException
 * @throws ConfigurationException
 * @throws IllegalArgumentException inputstream is null
 */
public AuthnRequestType getAuthnRequestType(InputStream is) throws ConfigurationException, ProcessingException, ParsingException {
    if (is == null)
        throw logger.nullArgumentError("InputStream");
    Document samlDocument = DocumentUtil.getDocument(is);
    SAMLParser samlParser = SAMLParser.getInstance();
    JAXPValidationUtil.checkSchemaValidation(samlDocument);
    AuthnRequestType requestType = (AuthnRequestType) samlParser.parse(samlDocument);
    samlDocumentHolder = new SAMLDocumentHolder(requestType, samlDocument);
    return requestType;
}
Also used : SAMLDocumentHolder(org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder) AuthnRequestType(org.keycloak.dom.saml.v2.protocol.AuthnRequestType) SAMLParser(org.keycloak.saml.processing.core.parsers.saml.SAMLParser) Document(org.w3c.dom.Document)

Aggregations

SAMLDocumentHolder (org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder)83 Test (org.junit.Test)70 SamlClientBuilder (org.keycloak.testsuite.util.SamlClientBuilder)62 ResponseType (org.keycloak.dom.saml.v2.protocol.ResponseType)35 StatusResponseType (org.keycloak.dom.saml.v2.protocol.StatusResponseType)29 Document (org.w3c.dom.Document)20 IOException (java.io.IOException)19 JBossSAMLURIConstants (org.keycloak.saml.common.constants.JBossSAMLURIConstants)18 ArtifactResponseType (org.keycloak.dom.saml.v2.protocol.ArtifactResponseType)17 AuthnRequestType (org.keycloak.dom.saml.v2.protocol.AuthnRequestType)14 URI (java.net.URI)12 List (java.util.List)12 Response (javax.ws.rs.core.Response)12 Matchers.containsString (org.hamcrest.Matchers.containsString)12 ClientRepresentation (org.keycloak.representations.idm.ClientRepresentation)12 Matchers (org.keycloak.testsuite.util.Matchers)12 SamlClient (org.keycloak.testsuite.util.SamlClient)12 Matchers.is (org.hamcrest.Matchers.is)11 Assert.assertThat (org.junit.Assert.assertThat)11 Matchers.notNullValue (org.hamcrest.Matchers.notNullValue)10