VYPR
High severity8.1NVD Advisory· Published Mar 18, 2026· Updated Mar 18, 2026

Keycloak: keycloak: unauthorized authentication via disabled saml identity provider

CVE-2026-2603

Description

A flaw was found in Keycloak. A remote attacker could bypass security controls by sending a valid SAML response from an external Identity Provider (IdP) to the Keycloak SAML endpoint for IdP-initiated broker logins. This allows the attacker to complete broker logins even when the SAML Identity Provider is disabled, leading to unauthorized authentication.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

An attacker can bypass disabled SAML IdP checks in Keycloak, completing broker logins via crafted SAML responses.

Vulnerability

Description

CVE-2026-2603 is a flaw in Keycloak where the identity broker service fails to enforce the disabled status of a SAML Identity Provider (IdP) when processing IdP-initiated broker login flows [1][3]. The root cause is that the code path handling SAML responses from external IdPs does not check whether the IdP model is enabled; it only looks up the provider by alias and proceeds with authentication [2][4]. This oversight means that even if an administrator has disabled a SAML IdP, the broker flow continues as if the provider were active.

Attack

Vector and Exploitation

To exploit this, an attacker must be able to send a crafted SAML response to the Keycloak SAML endpoint used for IdP-initiated logins [1]. The attacker does not need to compromise the external IdP; they can forge a SAML assertion from a disabled IdP, as long as they know the provider alias and can reach the endpoint [3]. No prior authentication to Keycloak is required, making the attack surface broad for exposed SAML endpoints [1].

Impact

A successful exploit allows the attacker to authenticate to applications relying on Keycloak as if they had valid credentials from the disabled SAML IdP [1][3]. Since the IdP is disabled, this effectively bypasses the administrator's intent to block that trust relationship. The attacker gains unauthorized access to any resource protected by realm roles or group mappings that depend on the disabled IdP [3].

Mitigation

Red Hat and the Keycloak project have released a fix that introduces a helper method getIdentityProviderModel which raises an exception if the IdP model is null or not enabled [2][4]. Patched versions are included in advisories RHSA-2026:3925 (RHEL) and are part of the upstream Keycloak commits [3]. Users should apply the latest updates to their Keycloak installations. As of publication, the flaw has not been added to CISA's Known Exploited Vulnerabilities catalog, but given the low attack complexity, administrators should prioritize patching [1].

AI Insight generated on May 18, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

3
  • Red Hat/Red Hat build of Keycloak 26.2.14v5
    cpe:/a:redhat:build_keycloak:26.2::el9
  • Red Hat/Red Hat build of Keycloak 26.4.10v5
    cpe:/a:redhat:build_keycloak:26.4::el9

Patches

2
8ed7e59dc08d

Enforce disabled checks when processing brokering flows

https://github.com/keycloak/keycloakPedro IgorMar 7, 2026via ghsa
7 files changed · +101 13
  • server-spi-private/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java+12 2 modified
    @@ -22,6 +22,7 @@
     import java.util.HashSet;
     import java.util.List;
     import java.util.Map;
    +import java.util.Objects;
     import java.util.Set;
     
     import org.keycloak.models.Constants;
    @@ -53,15 +54,24 @@ public class BrokeredIdentityContext {
         private AuthenticationSessionModel authenticationSession;
     
         public BrokeredIdentityContext(String id, IdentityProviderModel idpConfig) {
    -        if (id == null) {
    -            throw new RuntimeException("No identifier provider for identity.");
    +        Objects.requireNonNull(id, "id must not be null");
    +        Objects.requireNonNull(idpConfig, "Identity provider config must not be null");
    +
    +        if (!idpConfig.isEnabled()) {
    +            throw new IdentityBrokerException("Identity provider is disabled");
             }
     
             this.id = id;
             this.idpConfig = idpConfig;
         }
     
         public BrokeredIdentityContext(IdentityProviderModel idpConfig) {
    +        Objects.requireNonNull(idpConfig, "Identity provider config must not be null");
    +
    +        if (!idpConfig.isEnabled()) {
    +            throw new IdentityBrokerException("Identity provider is disabled");
    +        }
    +
             this.idpConfig = idpConfig;
         }
     
    
  • services/src/main/java/org/keycloak/authentication/authenticators/broker/util/SerializedBrokeredIdentityContext.java+1 1 modified
    @@ -268,7 +268,7 @@ public BrokeredIdentityContext deserialize(KeycloakSession session, Authenticati
             RealmModel realm = authSession.getRealm();
             IdentityProviderModel idpConfig = session.identityProviders().getByAlias(getIdentityProviderId());
     
    -        if (idpConfig == null) {
    +        if (idpConfig == null || !idpConfig.isEnabled()) {
                 throw new ModelException("Can't find identity provider with ID " + getIdentityProviderId() + " in realm " + realm.getName());
             }
     
    
  • services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java+14 9 modified
    @@ -131,11 +131,6 @@
     
     import static org.keycloak.broker.provider.AbstractIdentityProvider.BROKER_REGISTERED_NEW_USER;
     
    -/**
    - * <p></p>
    - *
    - * @author Pedro Igor
    - */
     public class IdentityBrokerService implements UserAuthenticationIdentityProvider.AuthenticationCallback {
     
         // Authentication session note, which references identity provider that is currently linked
    @@ -302,7 +297,7 @@ public Response clientInitiatedAccountLinking(@PathParam("provider_alias") Strin
             }
     
     
    -        IdentityProviderModel identityProviderModel = session.identityProviders().getByAlias(providerAlias);
    +        IdentityProviderModel identityProviderModel = getIdentityProviderModel(session, providerAlias);
             if (identityProviderModel == null) {
                 event.error(Errors.UNKNOWN_IDENTITY_PROVIDER);
                 UriBuilder builder = UriBuilder.fromUri(redirectUri)
    @@ -342,6 +337,16 @@ public Response clientInitiatedAccountLinking(@PathParam("provider_alias") Strin
             return performClientInitiatedAccountLogin(providerAlias, clientSessionCode);
         }
     
    +    private static IdentityProviderModel getIdentityProviderModel(KeycloakSession session, String providerAlias) {
    +        IdentityProviderModel model = session.identityProviders().getByAlias(providerAlias);
    +
    +        if (model == null || !model.isEnabled()) {
    +            throw new IdentityBrokerException("Identity Provider [" + providerAlias + "] not found.");
    +        }
    +
    +        return model;
    +    }
    +
         public Response performClientInitiatedAccountLogin(String providerAlias, ClientSessionCode<AuthenticationSessionModel> clientSessionCode) {
             try {
                 UserAuthenticationIdentityProvider<?> identityProvider = getIdentityProvider(session, providerAlias);
    @@ -395,7 +400,7 @@ public Response performLogin(@PathParam("provider_alias") String providerAlias,
     
                 ClientSessionCode<AuthenticationSessionModel> clientSessionCode = new ClientSessionCode<>(session, realmModel, authSession);
                 clientSessionCode.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name());
    -            IdentityProviderModel identityProviderModel = session.identityProviders().getByAlias(providerAlias);
    +            IdentityProviderModel identityProviderModel = getIdentityProviderModel(session, providerAlias);
                 if (identityProviderModel == null) {
                     throw new IdentityBrokerException("Identity Provider [" + providerAlias + "] not found.");
                 }
    @@ -1363,7 +1368,7 @@ private Response notFound(String message) {
         }
     
         public static UserAuthenticationIdentityProvider<?> getIdentityProvider(KeycloakSession session, String alias) {
    -        IdentityProviderModel identityProviderModel = session.identityProviders().getByAlias(alias);
    +        IdentityProviderModel identityProviderModel = getIdentityProviderModel(session, alias);
             UserAuthenticationIdentityProvider<?> identityProvider = getIdentityProvider(session, identityProviderModel, UserAuthenticationIdentityProvider.class);
             if (identityProvider == null) {
                 throw new IdentityBrokerException("Identity Provider [" + alias + "] not found.");
    @@ -1396,7 +1401,7 @@ private static IdentityProviderFactory<?> getIdentityProviderFactory(KeycloakSes
         }
     
         private IdentityProviderModel getIdentityProviderConfig(String providerAlias) {
    -        IdentityProviderModel model = session.identityProviders().getByAlias(providerAlias);
    +        IdentityProviderModel model = getIdentityProviderModel(session, providerAlias);
             if (model == null) {
                 throw new IdentityBrokerException("Configuration for identity provider [" + providerAlias + "] not found.");
             }
    
  • services/src/test/java/org/keycloak/test/broker/oidc/AbstractOAuth2IdentityProviderTest.java+1 0 modified
    @@ -175,6 +175,7 @@ private static class TestProvider extends AbstractOAuth2IdentityProvider<OAuth2I
     
     		public TestProvider(OAuth2IdentityProviderConfig config) {
     			super(null, config);
    +            config.setEnabled(true);
     		}
     
     		@Override
    
  • services/src/test/java/org/keycloak/test/broker/saml/XPathAttributeMapperTest.java+9 1 modified
    @@ -115,7 +115,7 @@ private String testMapping(String attributeValue, String xpath, String attribute
             config.put(XPathAttributeMapper.ATTRIBUTE_NAME, attributeNameToSearch);
             config.put(XPathAttributeMapper.USER_ATTRIBUTE, attribute);
             config.put(XPathAttributeMapper.ATTRIBUTE_XPATH, xpath);
    -        BrokeredIdentityContext context = new BrokeredIdentityContext("brokeredIdentityContext", new IdentityProviderModel());
    +        BrokeredIdentityContext context = new BrokeredIdentityContext("brokeredIdentityContext", createIdentityProviderModel());
             AssertionType assertion = AssertionUtil.createAssertion("assertionId", NameIDType.deserializeFromString("nameIDType"));
             AttributeStatementType statement = new AttributeStatementType();
             assertion.addStatement(statement);
    @@ -137,4 +137,12 @@ private String testMapping(String attributeValue, String xpath, String attribute
             Object userAttributes = context.getContextData().get("user.attributes." + attribute);
             return userAttributes == null ? null : ((List<?>) userAttributes).get(0).toString();
         }
    +
    +    private IdentityProviderModel createIdentityProviderModel() {
    +        IdentityProviderModel model = new IdentityProviderModel();
    +
    +        model.setEnabled(true);
    +
    +        return model;
    +    }
     }
    
  • testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedBrokerTest.java+33 0 modified
    @@ -44,6 +44,7 @@
     
     import static org.hamcrest.MatcherAssert.assertThat;
     import static org.hamcrest.Matchers.hasItems;
    +import static org.hamcrest.Matchers.is;
     import static org.hamcrest.Matchers.not;
     import static org.hamcrest.Matchers.notNullValue;
     import static org.junit.Assert.assertEquals;
    @@ -549,4 +550,36 @@ public void testWithLinkedFederationProvider() {
                 removeUserByUsername(adminClient.realm(bc.consumerRealmName()), "test-user-noemail");
             }
         }
    +
    +    @Test
    +    public void testDisabledBroker() {
    +        loginUser();
    +        logoutFromConsumerRealm();
    +        AccountHelper.logout(adminClient.realm(bc.providerRealmName()), bc.getUserLogin());
    +
    +        oauth.clientId("broker-app");
    +        loginPage.open(bc.consumerRealmName());
    +
    +        RealmResource realm = adminClient.realm(bc.consumerRealmName());
    +        identityProviderResource = realm.identityProviders().get(bc.getIDPAlias());
    +        IdentityProviderRepresentation idpRep = identityProviderResource.toRepresentation();
    +        idpRep.setEnabled(false);
    +        identityProviderResource.update(idpRep);
    +        waitForPage(driver, "sign in to", true);
    +        loginPage.clickSocial(bc.getIDPAlias());
    +        errorPage.assertCurrent();
    +        assertThat(errorPage.getError(), is("Could not send authentication request to identity provider."));
    +
    +        idpRep.setEnabled(true);
    +        identityProviderResource.update(idpRep);
    +        oauth.openLoginForm();
    +        loginPage.clickSocial(bc.getIDPAlias());
    +        waitForPage(driver, "sign in to", true);
    +        Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
    +        idpRep.setEnabled(false);
    +        identityProviderResource.update(idpRep);
    +        loginPage.login(bc.getUserLogin(), bc.getUserPassword());
    +        errorPage.assertCurrent();
    +        assertThat(errorPage.getError(), is("Page not found"));
    +    }
     }
    
  • testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlIdPInitiatedSsoTest.java+31 0 modified
    @@ -136,6 +136,7 @@ public void resetPrincipalType() {
             IdentityProviderRepresentation rep = idp.toRepresentation();
             rep.getConfig().put(SAMLIdentityProviderConfig.NAME_ID_POLICY_FORMAT, JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get());
             rep.getConfig().put(SAMLIdentityProviderConfig.PRINCIPAL_TYPE, SamlPrincipalType.SUBJECT.name());
    +        rep.setEnabled(true);
             idp.update(rep);
         }
     
    @@ -188,6 +189,36 @@ public void testProviderIdpInitiatedLogin() throws Exception {
             assertThat(driver.findElement(By.tagName("a")).getAttribute("id"), containsString("account"));
         }
     
    +    @Test
    +    public void testDisabledBroker() throws Exception {
    +        driver.navigate().to(getSamlIdpInitiatedUrl(REALM_PROV_NAME, "samlbroker"));
    +
    +        waitForPage("sign in to", true);
    +
    +        assertThat("Driver should be on the provider realm page right now",
    +                driver.getCurrentUrl(), containsString("/auth/realms/" + REALM_PROV_NAME + "/"));
    +
    +        log.debug("Logging in");
    +        accountLoginPage.login(PROVIDER_REALM_USER_NAME, PROVIDER_REALM_USER_PASSWORD);
    +
    +        waitForPage("update account information", false);
    +
    +        Assert.assertTrue(updateAccountInformationPage.isCurrent());
    +        assertThat("We must be on consumer realm right now",
    +                driver.getCurrentUrl(), containsString("/auth/realms/" + REALM_CONS_NAME + "/"));
    +
    +        log.debug("Updating info on updateAccount page");
    +        updateAccountInformationPage.updateAccountInformation(CONSUMER_CHOSEN_USERNAME, "test@localhost", "Firstname", "Lastname");
    +
    +        IdentityProviderResource idp = adminClient.realm(REALM_CONS_NAME).identityProviders().get("saml-leaf");
    +        IdentityProviderRepresentation rep = idp.toRepresentation();
    +        rep.setEnabled(false);
    +        idp.update(rep);
    +        driver.navigate().to(getSamlIdpInitiatedUrl(REALM_PROV_NAME, "samlbroker"));
    +        errorPage.assertCurrent();
    +        assertThat(errorPage.getError(), is("Page not found"));
    +    }
    +
         private String getSamlIdpInitiatedUrl(String realmName, String samlIdpInitiatedSsoUrlName) {
             return getAuthRoot() + "/auth/realms/" + realmName + "/protocol/saml/clients/" + samlIdpInitiatedSsoUrlName;
         }
    
4fd5367e6cc2

Enforce disabled checks when processing brokering flows (#367)

https://github.com/keycloak/keycloakPedro IgorFeb 25, 2026via ghsa
7 files changed · +101 13
  • server-spi-private/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java+12 2 modified
    @@ -22,6 +22,7 @@
     import java.util.HashSet;
     import java.util.List;
     import java.util.Map;
    +import java.util.Objects;
     import java.util.Set;
     
     import org.keycloak.models.Constants;
    @@ -53,15 +54,24 @@ public class BrokeredIdentityContext {
         private AuthenticationSessionModel authenticationSession;
     
         public BrokeredIdentityContext(String id, IdentityProviderModel idpConfig) {
    -        if (id == null) {
    -            throw new RuntimeException("No identifier provider for identity.");
    +        Objects.requireNonNull(id, "id must not be null");
    +        Objects.requireNonNull(idpConfig, "Identity provider config must not be null");
    +
    +        if (!idpConfig.isEnabled()) {
    +            throw new IdentityBrokerException("Identity provider is disabled");
             }
     
             this.id = id;
             this.idpConfig = idpConfig;
         }
     
         public BrokeredIdentityContext(IdentityProviderModel idpConfig) {
    +        Objects.requireNonNull(idpConfig, "Identity provider config must not be null");
    +
    +        if (!idpConfig.isEnabled()) {
    +            throw new IdentityBrokerException("Identity provider is disabled");
    +        }
    +
             this.idpConfig = idpConfig;
         }
     
    
  • services/src/main/java/org/keycloak/authentication/authenticators/broker/util/SerializedBrokeredIdentityContext.java+1 1 modified
    @@ -268,7 +268,7 @@ public BrokeredIdentityContext deserialize(KeycloakSession session, Authenticati
             RealmModel realm = authSession.getRealm();
             IdentityProviderModel idpConfig = session.identityProviders().getByAlias(getIdentityProviderId());
     
    -        if (idpConfig == null) {
    +        if (idpConfig == null || !idpConfig.isEnabled()) {
                 throw new ModelException("Can't find identity provider with ID " + getIdentityProviderId() + " in realm " + realm.getName());
             }
     
    
  • services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java+14 9 modified
    @@ -130,11 +130,6 @@
     
     import static org.keycloak.broker.provider.AbstractIdentityProvider.BROKER_REGISTERED_NEW_USER;
     
    -/**
    - * <p></p>
    - *
    - * @author Pedro Igor
    - */
     public class IdentityBrokerService implements UserAuthenticationIdentityProvider.AuthenticationCallback {
     
         // Authentication session note, which references identity provider that is currently linked
    @@ -301,7 +296,7 @@ public Response clientInitiatedAccountLinking(@PathParam("provider_alias") Strin
             }
     
     
    -        IdentityProviderModel identityProviderModel = session.identityProviders().getByAlias(providerAlias);
    +        IdentityProviderModel identityProviderModel = getIdentityProviderModel(session, providerAlias);
             if (identityProviderModel == null) {
                 event.error(Errors.UNKNOWN_IDENTITY_PROVIDER);
                 UriBuilder builder = UriBuilder.fromUri(redirectUri)
    @@ -341,6 +336,16 @@ public Response clientInitiatedAccountLinking(@PathParam("provider_alias") Strin
             return performClientInitiatedAccountLogin(providerAlias, clientSessionCode);
         }
     
    +    private static IdentityProviderModel getIdentityProviderModel(KeycloakSession session, String providerAlias) {
    +        IdentityProviderModel model = session.identityProviders().getByAlias(providerAlias);
    +
    +        if (model == null || !model.isEnabled()) {
    +            throw new IdentityBrokerException("Identity Provider [" + providerAlias + "] not found.");
    +        }
    +
    +        return model;
    +    }
    +
         public Response performClientInitiatedAccountLogin(String providerAlias, ClientSessionCode<AuthenticationSessionModel> clientSessionCode) {
             try {
                 UserAuthenticationIdentityProvider<?> identityProvider = getIdentityProvider(session, providerAlias);
    @@ -394,7 +399,7 @@ public Response performLogin(@PathParam("provider_alias") String providerAlias,
     
                 ClientSessionCode<AuthenticationSessionModel> clientSessionCode = new ClientSessionCode<>(session, realmModel, authSession);
                 clientSessionCode.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name());
    -            IdentityProviderModel identityProviderModel = session.identityProviders().getByAlias(providerAlias);
    +            IdentityProviderModel identityProviderModel = getIdentityProviderModel(session, providerAlias);
                 if (identityProviderModel == null) {
                     throw new IdentityBrokerException("Identity Provider [" + providerAlias + "] not found.");
                 }
    @@ -1352,7 +1357,7 @@ private Response notFound(String message) {
         }
     
         public static UserAuthenticationIdentityProvider<?> getIdentityProvider(KeycloakSession session, String alias) {
    -        IdentityProviderModel identityProviderModel = session.identityProviders().getByAlias(alias);
    +        IdentityProviderModel identityProviderModel = getIdentityProviderModel(session, alias);
             UserAuthenticationIdentityProvider<?> identityProvider = getIdentityProvider(session, identityProviderModel, UserAuthenticationIdentityProvider.class);
             if (identityProvider == null) {
                 throw new IdentityBrokerException("Identity Provider [" + alias + "] not found.");
    @@ -1383,7 +1388,7 @@ private static IdentityProviderFactory<?> getIdentityProviderFactory(KeycloakSes
         }
     
         private IdentityProviderModel getIdentityProviderConfig(String providerAlias) {
    -        IdentityProviderModel model = session.identityProviders().getByAlias(providerAlias);
    +        IdentityProviderModel model = getIdentityProviderModel(session, providerAlias);
             if (model == null) {
                 throw new IdentityBrokerException("Configuration for identity provider [" + providerAlias + "] not found.");
             }
    
  • services/src/test/java/org/keycloak/test/broker/oidc/AbstractOAuth2IdentityProviderTest.java+1 0 modified
    @@ -175,6 +175,7 @@ private static class TestProvider extends AbstractOAuth2IdentityProvider<OAuth2I
     
     		public TestProvider(OAuth2IdentityProviderConfig config) {
     			super(null, config);
    +            config.setEnabled(true);
     		}
     
     		@Override
    
  • services/src/test/java/org/keycloak/test/broker/saml/XPathAttributeMapperTest.java+9 1 modified
    @@ -115,7 +115,7 @@ private String testMapping(String attributeValue, String xpath, String attribute
             config.put(XPathAttributeMapper.ATTRIBUTE_NAME, attributeNameToSearch);
             config.put(XPathAttributeMapper.USER_ATTRIBUTE, attribute);
             config.put(XPathAttributeMapper.ATTRIBUTE_XPATH, xpath);
    -        BrokeredIdentityContext context = new BrokeredIdentityContext("brokeredIdentityContext", new IdentityProviderModel());
    +        BrokeredIdentityContext context = new BrokeredIdentityContext("brokeredIdentityContext", createIdentityProviderModel());
             AssertionType assertion = AssertionUtil.createAssertion("assertionId", NameIDType.deserializeFromString("nameIDType"));
             AttributeStatementType statement = new AttributeStatementType();
             assertion.addStatement(statement);
    @@ -137,4 +137,12 @@ private String testMapping(String attributeValue, String xpath, String attribute
             Object userAttributes = context.getContextData().get("user.attributes." + attribute);
             return userAttributes == null ? null : ((List<?>) userAttributes).get(0).toString();
         }
    +
    +    private IdentityProviderModel createIdentityProviderModel() {
    +        IdentityProviderModel model = new IdentityProviderModel();
    +
    +        model.setEnabled(true);
    +
    +        return model;
    +    }
     }
    
  • testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedBrokerTest.java+33 0 modified
    @@ -56,6 +56,7 @@
     
     import static org.hamcrest.MatcherAssert.assertThat;
     import static org.hamcrest.Matchers.hasItems;
    +import static org.hamcrest.Matchers.is;
     import static org.hamcrest.Matchers.not;
     import static org.hamcrest.Matchers.notNullValue;
     import static org.junit.Assert.assertEquals;
    @@ -614,4 +615,36 @@ public void testWithLinkedFederationProvider() {
                 removeUserByUsername(adminClient.realm(bc.consumerRealmName()), "test-user-noemail");
             }
         }
    +
    +    @Test
    +    public void testDisabledBroker() {
    +        loginUser();
    +        logoutFromConsumerRealm();
    +        AccountHelper.logout(adminClient.realm(bc.providerRealmName()), bc.getUserLogin());
    +
    +        oauth.clientId("broker-app");
    +        loginPage.open(bc.consumerRealmName());
    +
    +        RealmResource realm = adminClient.realm(bc.consumerRealmName());
    +        identityProviderResource = realm.identityProviders().get(bc.getIDPAlias());
    +        IdentityProviderRepresentation idpRep = identityProviderResource.toRepresentation();
    +        idpRep.setEnabled(false);
    +        identityProviderResource.update(idpRep);
    +        waitForPage(driver, "sign in to", true);
    +        loginPage.clickSocial(bc.getIDPAlias());
    +        errorPage.assertCurrent();
    +        assertThat(errorPage.getError(), is("Could not send authentication request to identity provider."));
    +
    +        idpRep.setEnabled(true);
    +        identityProviderResource.update(idpRep);
    +        oauth.openLoginForm();
    +        loginPage.clickSocial(bc.getIDPAlias());
    +        waitForPage(driver, "sign in to", true);
    +        Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
    +        idpRep.setEnabled(false);
    +        identityProviderResource.update(idpRep);
    +        loginPage.login(bc.getUserLogin(), bc.getUserPassword());
    +        errorPage.assertCurrent();
    +        assertThat(errorPage.getError(), is("Page not found"));
    +    }
     }
    
  • testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlIdPInitiatedSsoTest.java+31 0 modified
    @@ -136,6 +136,7 @@ public void resetPrincipalType() {
             IdentityProviderRepresentation rep = idp.toRepresentation();
             rep.getConfig().put(SAMLIdentityProviderConfig.NAME_ID_POLICY_FORMAT, JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get());
             rep.getConfig().put(SAMLIdentityProviderConfig.PRINCIPAL_TYPE, SamlPrincipalType.SUBJECT.name());
    +        rep.setEnabled(true);
             idp.update(rep);
         }
     
    @@ -188,6 +189,36 @@ public void testProviderIdpInitiatedLogin() throws Exception {
             assertThat(driver.findElement(By.tagName("a")).getAttribute("id"), containsString("account"));
         }
     
    +    @Test
    +    public void testDisabledBroker() throws Exception {
    +        driver.navigate().to(getSamlIdpInitiatedUrl(REALM_PROV_NAME, "samlbroker"));
    +
    +        waitForPage("sign in to", true);
    +
    +        assertThat("Driver should be on the provider realm page right now",
    +                driver.getCurrentUrl(), containsString("/auth/realms/" + REALM_PROV_NAME + "/"));
    +
    +        log.debug("Logging in");
    +        accountLoginPage.login(PROVIDER_REALM_USER_NAME, PROVIDER_REALM_USER_PASSWORD);
    +
    +        waitForPage("update account information", false);
    +
    +        Assert.assertTrue(updateAccountInformationPage.isCurrent());
    +        assertThat("We must be on consumer realm right now",
    +                driver.getCurrentUrl(), containsString("/auth/realms/" + REALM_CONS_NAME + "/"));
    +
    +        log.debug("Updating info on updateAccount page");
    +        updateAccountInformationPage.updateAccountInformation(CONSUMER_CHOSEN_USERNAME, "test@localhost", "Firstname", "Lastname");
    +
    +        IdentityProviderResource idp = adminClient.realm(REALM_CONS_NAME).identityProviders().get("saml-leaf");
    +        IdentityProviderRepresentation rep = idp.toRepresentation();
    +        rep.setEnabled(false);
    +        idp.update(rep);
    +        driver.navigate().to(getSamlIdpInitiatedUrl(REALM_PROV_NAME, "samlbroker"));
    +        errorPage.assertCurrent();
    +        assertThat(errorPage.getError(), is("Page not found"));
    +    }
    +
         private String getSamlIdpInitiatedUrl(String realmName, String samlIdpInitiatedSsoUrlName) {
             return getAuthRoot() + "/auth/realms/" + realmName + "/protocol/saml/clients/" + samlIdpInitiatedSsoUrlName;
         }
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

13

News mentions

0

No linked articles in our index yet.