Date: Monday, April 4, 2022 @ 23:08:06 Author: artafinde Revision: 1181415
keycloak: backport fix for CVE-2021-3827 https://security.archlinux.org/CVE-2021-3827 Added: keycloak/trunk/0001-KEYCLOAK-19177-Disable-ECP-flow-by-default-for-all-S.patch Modified: keycloak/trunk/PKGBUILD -----------------------------------------------------------------+ 0001-KEYCLOAK-19177-Disable-ECP-flow-by-default-for-all-S.patch | 367 ++++++++++ PKGBUILD | 9 2 files changed, 373 insertions(+), 3 deletions(-) Added: 0001-KEYCLOAK-19177-Disable-ECP-flow-by-default-for-all-S.patch =================================================================== --- 0001-KEYCLOAK-19177-Disable-ECP-flow-by-default-for-all-S.patch (rev 0) +++ 0001-KEYCLOAK-19177-Disable-ECP-flow-by-default-for-all-S.patch 2022-04-04 23:08:06 UTC (rev 1181415) @@ -0,0 +1,367 @@ +From 44000caaf5051d7f218d1ad79573bd3d175cad0d Mon Sep 17 00:00:00 2001 +From: Michal Hajas <mha...@redhat.com> +Date: Mon, 4 Oct 2021 15:26:29 +0200 +Subject: [PATCH] KEYCLOAK-19177 Disable ECP flow by default for all Saml + clients; ecp flow creates only transient users sessions + +--- + .../keycloak/protocol/saml/SamlClient.java | 8 ++ + .../protocol/saml/SamlConfigAttributes.java | 1 + + .../protocol/saml/SamlProtocolFactory.java | 4 + + .../saml/SamlRepresentationAttributes.java | 5 ++ + .../profile/ecp/SamlEcpProfileService.java | 11 ++- + .../testsuite/saml/SOAPBindingTest.java | 79 ++++++++++++++++++- + .../adapter-test/keycloak-saml/testsaml.json | 3 +- + .../clients/settings/ClientSettingsForm.java | 2 + + .../console/clients/AbstractClientTest.java | 3 +- + .../messages/admin-messages_en.properties | 2 + + .../admin/resources/js/controllers/clients.js | 14 ++++ + .../resources/partials/client-detail.html | 7 ++ + 12 files changed, 135 insertions(+), 4 deletions(-) + +diff --git a/services/src/main/java/org/keycloak/protocol/saml/SamlClient.java b/services/src/main/java/org/keycloak/protocol/saml/SamlClient.java +index 1b8f23495e..9cf0cd1847 100755 +--- a/services/src/main/java/org/keycloak/protocol/saml/SamlClient.java ++++ b/services/src/main/java/org/keycloak/protocol/saml/SamlClient.java +@@ -120,6 +120,14 @@ public class SamlClient extends ClientConfigResolver { + client.setAttribute(SamlConfigAttributes.SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE, Boolean.toString(val)); + } + ++ public boolean allowECPFlow() { ++ return "true".equals(resolveAttribute(SamlConfigAttributes.SAML_ALLOW_ECP_FLOW)); ++ } ++ ++ public void setAllowECPFlow(boolean val) { ++ client.setAttribute(SamlConfigAttributes.SAML_ALLOW_ECP_FLOW, Boolean.toString(val)); ++ } ++ + public boolean forceArtifactBinding(){ + return "true".equals(resolveAttribute(SamlConfigAttributes.SAML_ARTIFACT_BINDING)); + } +diff --git a/services/src/main/java/org/keycloak/protocol/saml/SamlConfigAttributes.java b/services/src/main/java/org/keycloak/protocol/saml/SamlConfigAttributes.java +index 59f27f50ab..02a41c4831 100755 +--- a/services/src/main/java/org/keycloak/protocol/saml/SamlConfigAttributes.java ++++ b/services/src/main/java/org/keycloak/protocol/saml/SamlConfigAttributes.java +@@ -44,4 +44,5 @@ public interface SamlConfigAttributes { + String SAML_ENCRYPTION_PRIVATE_KEY_ATTRIBUTE = "saml.encryption." + CertificateInfoHelper.PRIVATE_KEY; + String SAML_ASSERTION_LIFESPAN = "saml.assertion.lifespan"; + String SAML_ARTIFACT_BINDING_IDENTIFIER = "saml.artifact.binding.identifier"; ++ String SAML_ALLOW_ECP_FLOW = "saml.allow.ecp.flow"; + } +diff --git a/services/src/main/java/org/keycloak/protocol/saml/SamlProtocolFactory.java b/services/src/main/java/org/keycloak/protocol/saml/SamlProtocolFactory.java +index fae3e4de09..772885553b 100755 +--- a/services/src/main/java/org/keycloak/protocol/saml/SamlProtocolFactory.java ++++ b/services/src/main/java/org/keycloak/protocol/saml/SamlProtocolFactory.java +@@ -154,6 +154,10 @@ public class SamlProtocolFactory extends AbstractLoginProtocolFactory { + client.setForceNameIDFormat(false); + } + ++ if (rep.getAllowEcpFlow() == null) { ++ client.setAllowECPFlow(false); ++ } ++ + if (rep.getSamlServerSignature() == null) { + client.setRequiresRealmSignature(true); + } +diff --git a/services/src/main/java/org/keycloak/protocol/saml/SamlRepresentationAttributes.java b/services/src/main/java/org/keycloak/protocol/saml/SamlRepresentationAttributes.java +index a64b847b80..e4da38eee9 100755 +--- a/services/src/main/java/org/keycloak/protocol/saml/SamlRepresentationAttributes.java ++++ b/services/src/main/java/org/keycloak/protocol/saml/SamlRepresentationAttributes.java +@@ -61,6 +61,11 @@ public class SamlRepresentationAttributes { + return getAttributes().get(SamlConfigAttributes.SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE); + } + ++ public String getAllowEcpFlow() { ++ if (getAttributes() == null) return null; ++ return getAttributes().get(SamlConfigAttributes.SAML_ALLOW_ECP_FLOW); ++ } ++ + public String getSamlArtifactBinding() { + if (getAttributes() == null) return null; + return getAttributes().get(SamlConfigAttributes.SAML_ARTIFACT_BINDING); +diff --git a/services/src/main/java/org/keycloak/protocol/saml/profile/ecp/SamlEcpProfileService.java b/services/src/main/java/org/keycloak/protocol/saml/profile/ecp/SamlEcpProfileService.java +index 7457381d22..f3202a7c3b 100755 +--- a/services/src/main/java/org/keycloak/protocol/saml/profile/ecp/SamlEcpProfileService.java ++++ b/services/src/main/java/org/keycloak/protocol/saml/profile/ecp/SamlEcpProfileService.java +@@ -26,6 +26,7 @@ import org.keycloak.models.RealmModel; + import org.keycloak.models.UserSessionModel; + import org.keycloak.models.utils.DefaultAuthenticationFlows; + import org.keycloak.protocol.saml.JaxrsSAML2BindingBuilder; ++import org.keycloak.protocol.saml.SamlClient; + import org.keycloak.protocol.saml.SamlConfigAttributes; + import org.keycloak.protocol.saml.SamlProtocol; + import org.keycloak.protocol.saml.SamlService; +@@ -36,6 +37,7 @@ import org.keycloak.saml.common.constants.JBossSAMLURIConstants; + import org.keycloak.saml.common.exceptions.ConfigurationException; + import org.keycloak.saml.common.exceptions.ProcessingException; + import org.keycloak.saml.validators.DestinationValidator; ++import org.keycloak.services.managers.AuthenticationManager; + import org.keycloak.sessions.AuthenticationSessionModel; + import org.w3c.dom.Document; + +@@ -44,7 +46,6 @@ import javax.xml.soap.SOAPException; + import javax.xml.soap.SOAPHeaderElement; + import java.io.IOException; + import java.io.InputStream; +-import java.util.Map; + import java.util.Objects; + + /** +@@ -79,6 +80,12 @@ public class SamlEcpProfileService extends SamlService { + + @Override + protected Response loginRequest(String relayState, AuthnRequestType requestAbstractType, ClientModel client) { ++ // Do not allow ECP login when client does not support it ++ if (!new SamlClient(client).allowECPFlow()) { ++ logger.errorf("Client %s is not allowed to execute ECP flow", client.getClientId()); ++ throw new RuntimeException("Client is not allowed to use ECP profile."); ++ } ++ + // force passive authentication when executing this profile + requestAbstractType.setIsPassive(true); + requestAbstractType.setDestination(session.getContext().getUri().getAbsolutePath()); +@@ -99,6 +106,8 @@ public class SamlEcpProfileService extends SamlService { + + @Override + protected Response newBrowserAuthentication(AuthenticationSessionModel authSession, boolean isPassive, boolean redirectToAuthentication, SamlProtocol samlProtocol) { ++ // Saml ECP flow creates only TRANSIENT user sessions ++ authSession.setClientNote(AuthenticationManager.USER_SESSION_PERSISTENT_STATE, UserSessionModel.SessionPersistenceState.TRANSIENT.toString()); + return super.newBrowserAuthentication(authSession, isPassive, redirectToAuthentication, createEcpSamlProtocol()); + } + +diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/SOAPBindingTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/SOAPBindingTest.java +index 4afbbbbe12..41007f70e9 100644 +--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/SOAPBindingTest.java ++++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/SOAPBindingTest.java +@@ -17,17 +17,34 @@ + package org.keycloak.testsuite.saml; + + import org.junit.Test; ++import org.keycloak.dom.saml.v2.SAML2Object; ++import org.keycloak.dom.saml.v2.assertion.AuthnStatementType; + import org.keycloak.dom.saml.v2.protocol.ResponseType; + import org.keycloak.dom.saml.v2.protocol.StatusResponseType; ++import org.keycloak.models.RealmModel; ++import org.keycloak.models.UserSessionModel; + import org.keycloak.protocol.saml.SamlConfigAttributes; ++import org.keycloak.saml.common.constants.JBossSAMLURIConstants; + import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder; + import org.keycloak.testsuite.updaters.ClientAttributeUpdater; + import org.keycloak.testsuite.util.SamlClientBuilder; + ++import javax.ws.rs.core.Response; ++import javax.xml.soap.MessageFactory; ++import javax.xml.soap.SOAPException; ++import javax.xml.soap.SOAPMessage; ++ ++import java.io.IOException; ++ ++import static org.hamcrest.MatcherAssert.assertThat; + import static org.hamcrest.Matchers.empty; ++import static org.hamcrest.Matchers.equalTo; + import static org.hamcrest.Matchers.instanceOf; ++import static org.hamcrest.Matchers.is; + import static org.hamcrest.Matchers.not; +-import static org.junit.Assert.assertThat; ++import static org.hamcrest.Matchers.nullValue; ++import static org.keycloak.testsuite.util.Matchers.isSamlResponse; ++import static org.keycloak.testsuite.util.Matchers.statusCodeIsHC; + import static org.keycloak.testsuite.util.SamlClient.Binding.POST; + import static org.keycloak.testsuite.util.SamlClient.Binding.SOAP; + +@@ -214,4 +231,64 @@ public class SOAPBindingTest extends AbstractSamlTest { + + assertThat(response.getSamlObject(), instanceOf(StatusResponseType.class)); + } ++ ++ @Test ++ public void soapBindingIsNotPossibleForClientsWithSamlEcpFlowAttributeFalse() { ++ // Disable ECP_FLOW_ENABLED switch ++ getCleanup().addCleanup(ClientAttributeUpdater.forClient(adminClient, REALM_NAME, SAML_CLIENT_ID_ECP_SP) ++ .setAttribute(SamlConfigAttributes.SAML_ALLOW_ECP_FLOW, "false") ++ .setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE, "false") ++ .setAttribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, "false") ++ .update()); ++ ++ new SamlClientBuilder() ++ .authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_ECP_SP, SAML_ASSERTION_CONSUMER_URL_ECP_SP, SOAP) ++ .basicAuthentication(bburkeUser) ++ .build() ++ .execute(response -> { ++ assertThat(response, statusCodeIsHC(Response.Status.INTERNAL_SERVER_ERROR)); ++ ++ try { ++ MessageFactory messageFactory = MessageFactory.newInstance(); ++ SOAPMessage soapMessage = messageFactory.createMessage(null, response.getEntity().getContent()); ++ String faultDetail = soapMessage.getSOAPBody().getFault().getDetail().getValue(); ++ assertThat(faultDetail, is(equalTo("Client is not allowed to use ECP profile."))); ++ } catch (SOAPException | IOException e) { ++ throw new RuntimeException(e); ++ } ++ }); ++ ++ } ++ ++ @Test ++ public void ecpFlowCreatesTransientSessions() { ++ // Disable ECP_FLOW_ENABLED switch ++ getCleanup().addCleanup(ClientAttributeUpdater.forClient(adminClient, REALM_NAME, SAML_CLIENT_ID_ECP_SP) ++ .setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE, "false") ++ .setAttribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, "false") ++ .update()); ++ ++ // Successfully login using ECP flow ++ SAML2Object samlObject = new SamlClientBuilder() ++ .authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_ECP_SP, SAML_ASSERTION_CONSUMER_URL_ECP_SP, SOAP) ++ .basicAuthentication(bburkeUser) ++ .build() ++ .executeAndTransform(SOAP::extractResponse).getSamlObject(); ++ ++ assertThat(samlObject, isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS)); ++ ResponseType loginResp1 = (ResponseType) samlObject; ++ AuthnStatementType sessionId = (AuthnStatementType) loginResp1.getAssertions().get(0).getAssertion().getStatements().iterator().next(); ++ ++ String userSessionId = sessionId.getSessionIndex().split("::")[0]; ++ ++ // Test that the user session with the given ID does not exist ++ testingClient.server().run(session -> { ++ RealmModel realmByName = session.realms().getRealmByName(REALM_NAME); ++ UserSessionModel userSession = session.sessions().getUserSession(realmByName, userSessionId); ++ ++ assertThat(userSession, nullValue()); ++ }); ++ ++ ++ } + } +diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json +index 604c32b39b..8b4f721ffd 100755 +--- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json ++++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json +@@ -716,7 +716,8 @@ + "saml.signature.algorithm": "RSA_SHA256", + "saml.client.signature": "true", + "saml.authnstatement": "true", +- "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw==" ++ "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw==", ++ "saml.allow.ecp.flow": "true" + } + }, + { +diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java +index 88de5cafb8..97f0fd55f3 100644 +--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java ++++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java +@@ -4,6 +4,7 @@ import java.util.ArrayList; + import java.util.List; + import java.util.Map; + ++import org.keycloak.protocol.saml.SamlConfigAttributes; + import org.keycloak.representations.idm.ClientRepresentation; + import org.keycloak.testsuite.console.page.clients.CreateClientForm; + import org.keycloak.testsuite.console.page.fragment.OnOffSwitch; +@@ -262,6 +263,7 @@ public class ClientSettingsForm extends CreateClientForm { + public static final String SAML_ASSERTION_CONSUMER_URL_REDIRECT = "saml_assertion_consumer_url_redirect"; + public static final String SAML_FORCE_NAME_ID_FORMAT = "saml_force_name_id_format"; + public static final String SAML_NAME_ID_FORMAT = "saml_name_id_format"; ++ public static final String SAML_ALLOW_ECP_FLOW = SamlConfigAttributes.SAML_ALLOW_ECP_FLOW; + public static final String SAML_SIGNATURE_CANONICALIZATION_METHOD = "saml_signature_canonicalization_method"; + public static final String SAML_SINGLE_LOGOUT_SERVICE_URL_POST = "saml_single_logout_service_url_post"; + public static final String SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT = "saml_single_logout_service_url_redirect"; +diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java +index 20c2f2aefd..86b148a7e8 100644 +--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java ++++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java +@@ -23,10 +23,10 @@ import static org.keycloak.testsuite.auth.page.login.OIDCLogin.OIDC; + import static org.keycloak.testsuite.auth.page.login.OIDCLogin.SAML; + import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_AUTHNSTATEMENT; + import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_CLIENT_SIGNATURE; ++import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_ALLOW_ECP_FLOW; + import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_FORCE_NAME_ID_FORMAT; + import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_FORCE_POST_BINDING; + import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_NAME_ID_FORMAT; +-import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_ONETIMEUSE_CONDITION; + import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_SERVER_SIGNATURE; + import static org.keycloak.testsuite.console.page.clients.settings.ClientSettingsForm.SAMLClientSettingsForm.SAML_SIGNATURE_ALGORITHM; + import static org.keycloak.testsuite.util.AttributesAssert.assertEqualsBooleanAttributes; +@@ -89,6 +89,7 @@ public abstract class AbstractClientTest extends AbstractConsoleTest { + attributes.put(SAML_SIGNATURE_ALGORITHM, "RSA_SHA256"); + attributes.put(SAML_FORCE_NAME_ID_FORMAT, "false"); + attributes.put(SAML_NAME_ID_FORMAT, "username"); ++ attributes.put(SAML_ALLOW_ECP_FLOW, "false"); + attributes.put(SamlConfigAttributes.SAML_ARTIFACT_BINDING_IDENTIFIER, ArtifactBindingUtils.computeArtifactBindingIdentifierString("saml")); + return attributes; + } +diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties +index 0cd25e66fa..3ead1891e2 100644 +--- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties ++++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties +@@ -371,6 +371,8 @@ front-channel-logout-session-required.tooltip=Specifying whether a sid (session + + force-name-id-format=Force Name ID Format + force-name-id-format.tooltip=Ignore requested NameID subject format and use admin console configured one. ++allow-ecp-flow=Allow ECP Flow ++allow-ecp-flow.tooltip=This client is allowed to use ECP flow for authenticating users. + name-id-format=Name ID Format + name-id-format.tooltip=The name ID format to use for the subject. + mapper.nameid.format.tooltip=Name ID Format using Mapper +diff --git a/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js b/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js +index ce245a5085..30a7faa65c 100755 +--- a/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js ++++ b/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js +@@ -1197,6 +1197,7 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, flows, $ro + $scope.samlEncrypt = false; + $scope.samlForcePostBinding = false; + $scope.samlForceNameIdFormat = false; ++ $scope.samlAllowECPFlow = false; + $scope.samlXmlKeyNameTranformer = $scope.xmlKeyNameTranformers[1]; + $scope.disableAuthorizationTab = !client.authorizationServicesEnabled; + $scope.disableServiceAccountRolesTab = !client.serviceAccountsEnabled; +@@ -1351,6 +1352,13 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, flows, $ro + $scope.samlForceNameIdFormat = false; + } + } ++ if ($scope.client.attributes["saml.allow.ecp.flow"]) { ++ if ($scope.client.attributes["saml.allow.ecp.flow"] == "true") { ++ $scope.samlAllowECPFlow = true; ++ } else { ++ $scope.samlAllowECPFlow = false; ++ } ++ } + if ($scope.client.attributes["saml.multivalued.roles"]) { + if ($scope.client.attributes["saml.multivalued.roles"] == "true") { + $scope.samlMultiValuedRoles = true; +@@ -1961,6 +1969,12 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, flows, $ro + } else { + $scope.clientEdit.attributes["saml_force_name_id_format"] = "false"; + ++ } ++ if ($scope.samlAllowECPFlow == true) { ++ $scope.clientEdit.attributes["saml.allow.ecp.flow"] = "true"; ++ } else { ++ $scope.clientEdit.attributes["saml.allow.ecp.flow"] = "false"; ++ + } + if ($scope.samlMultiValuedRoles == true) { + $scope.clientEdit.attributes["saml.multivalued.roles"] = "true"; +diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html +index 0b0b8c9a71..779aacef6e 100755 +--- a/themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html ++++ b/themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html +@@ -299,6 +299,13 @@ + </div> + <kc-tooltip>{{:: 'force-name-id-format.tooltip' | translate}}</kc-tooltip> + </div> ++ <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> ++ <label class="col-md-2 control-label" for="samlAllowECPFlow">{{:: 'allow-ecp-flow' | translate}}</label> ++ <div class="col-sm-6"> ++ <input ng-model="samlAllowECPFlow" ng-click="switchChange()" name="samlAllowECPFlow" id="samlAllowECPFlow" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> ++ </div> ++ <kc-tooltip>{{:: 'allow-ecp-flow.tooltip' | translate}}</kc-tooltip> ++ </div> + <div class="form-group" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlNameIdFormat">{{:: 'name-id-format' | translate}}</label> + <div class="col-sm-6"> +-- +2.35.1 + Modified: PKGBUILD =================================================================== --- PKGBUILD 2022-04-04 22:35:38 UTC (rev 1181414) +++ PKGBUILD 2022-04-04 23:08:06 UTC (rev 1181415) @@ -4,7 +4,7 @@ pkgname=keycloak pkgver=17.0.1 _java=11 -pkgrel=2 +pkgrel=3 pkgdesc="Open Source Identity and Access Management For Modern Applications and Services" arch=('any') url="https://www.keycloak.org/" @@ -21,18 +21,21 @@ keycloak.sysusers keycloak.tmpfiles common.sh - pin-java-version.patch) + pin-java-version.patch + 0001-KEYCLOAK-19177-Disable-ECP-flow-by-default-for-all-S.patch) sha512sums=('bd05538e91b7f0956b99f0bbee8cea190c381c9af04e428106d59ad45471b63bd5a88d17e98d00f965a86292149d8d3f1bd09a8becf7fd59430b99188b49c227' '1512520528b6893997b8a3c4899fbb84a897f604f279f64fc1228785a27544499f1c8951f8997129fb2b857d2d3c11b09fb9493f83faa20a0594c759adbe0823' '2e2ba147007ad74e38579a8838d79de47beac509b4bd1a14d7f80905953d79a7396d781f141b461ec688f5ceef9a1081a825a4ca8afc1ea12c178d8ae7f5a7dd' '155db40105c08d0aaa810ca5533dc16fc9f82060280541ede6fafd754d30b4844f6d10ace1417a5ad68d89fc54e1b9e6d906ce7ccf973f4ac964422211ed9a72' '4ae3f9fc42bfee602480c1c8cc2d65b44305622b426b74070758fe1c92a06ff12901ffebacbfe2ba34cbf783a8787f6073f74db3674c96e7a6109ed5b45d3a07' - 'c0351896427c7b7b73f446481a30dc735365a91541e7039cd613d1c7357c55c9559e388bc260e004c2a52211df1d23d9e24cc9c8ca956398f6e508ef96cb0ee2') + 'c0351896427c7b7b73f446481a30dc735365a91541e7039cd613d1c7357c55c9559e388bc260e004c2a52211df1d23d9e24cc9c8ca956398f6e508ef96cb0ee2' + 'f0395b70fd0a26fac0ce9b8aace4e6f1de7dc09e487b16005b6b944f0bf2b5845aa3c6fb247a9b9d94e7dfa79c8bd9308bcbb586a4d94776396b8de2223ebc19') prepare() { cd $pkgname-$pkgver patch -Np1 -i "$srcdir"/pin-java-version.patch + patch -Np1 -i "$srcdir"/0001-KEYCLOAK-19177-Disable-ECP-flow-by-default-for-all-S.patch } build() {