I am using sping boot embedded keycloak version 21. I have the default implementation of spi identity_provider as below, such that a file is created in META-INF/services by name “org.keycloak.broker.provider.IdentityProviderFactory” and below is declared. I dont have access to the below default implementations,
I am struggling to set my provider by providerId-“custom-saml” as default implementataion of the “saml” identity_provider. The spi “identity_provider” has three implementataions as mentioned above. The default one “saml” always takes precedence over my “custom-saml” which is extended from “saml” provider i.e. this implementation “org.keycloak.broker.saml.SAMLIdentityProviderFactory”
I have tried to set the default “identity_provider” using keycloak-server.json. I have used below and it works and my “custom-saml” provider is set as the default provider and not its parent provider from which I have extended. But the problem is that the other two providers “oidc” and “keycloak-oidc” stops showing up and they are no longer part of the classpath.
My question is how can I set the “CustomSAMLIdentityProviderFactory” mentioned above with providerId as “custom-saml” can be set as the default provider such that other SPI implementataion of “identity_provider” such as “oidc” and “keycloak-oidc” works as well?
Thanks @dasniko , big fan of your work and your YouTube channel has been of much help !!
I went through the link that you provided, multiple times in the past while trying to solve the issue. I have the keycloak spi “identity_provider”. I have two implementations of the SPI. One is “SAMLIdentityProviderFactory” which is the default one. I have extended “SAMLIdentityProviderFactory” to create “CustomSAMLIdentityProviderFactory”, which has my changes. I am trying to give precedence to “CustomSAMLIdentityProviderFactory” over the default provider “SAMLIdentityProviderFactory” . I have tried multiple things such as giving it higher order through order() and also tried by making changes in “keycloak-server.json”. When I make changes to “keycloak-server.json” as below, “CustomSAMLIdentityProviderFactory” is picked up at run time and it works fine. But other two implementataions of SPI “identity_provider” such as “oidc” and “keycloak-oidc” doesnt show up as I am selecting just one provider i.e. “CustomSAMLIdentityProviderFactory” as default in “keycloak-server.json”.
All I am trying to do is change the default value of “wantAuthRequestSigned” to “true” and auto select the “first broker login” to “custom first broker login”, so that the user doesnt have to manually select both. Can you think of an another way to achieve this auto-selection, other than by creating provider that is not working as mentioned above ? Thanks in advance.
I‘m usually just implement my custom provider and factory. The factory returns the same Id like the one I want to override but I return a higher order (>0). That‘s it. Nothing else. No obscure json file, no nothing. It just works.
I had tried your suggested steps in the past. It didnt work. Tried something like below. Let me check if I can find some other way to auto-select the value of “wantAuthnRequestsSigned”, “first broker login”, etc instead of asking the user to select manually during IDP creation.
import org.keycloak.broker.saml.SAMLIdentityProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.util.Map;
public class CustomSAMLIdentityProviderFactory extends SAMLIdentityProviderFactory {
private static final Logger LOG = LoggerFactory.getLogger(CustomSAMLIdentityProviderFactory.class);
@Override
public Map<String, String> parseConfig(KeycloakSession session, InputStream inputStream) {
try {
Map<String, String> config = super.parseConfig(session, inputStream);
config.put("wantAuthnRequestsSigned", "true");
return config;
} catch (Exception e) {
LOG.error("Error parsing configuration: {}", e.getMessage());
throw new RuntimeException("Failed to parse configuration", e);
}
}
@Override
public String getId() {
return PROVIDER_ID;
}
@Override
public int order() {
return 10;
}
}