diff --git a/docker-compose.yml b/docker-compose.yml index 04c6427..c7af91a 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: KEYCLOAK_ADMIN_PASSWORD: admin DEBUG_PORT: '*:8787' DEBUG: 'true' - command: ['start-dev', '--debug', '--import-realm'] + command: ['start-dev', '--debug', '--import-realm', '--features=organization'] ports: - 8080:8080 - 8443:8443 diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/AbstractHomeIdpDiscoveryAuthenticatorFactory.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/AbstractHomeIdpDiscoveryAuthenticatorFactory.java index 2c0e2cf..157a963 100644 --- a/src/main/java/de/sventorben/keycloak/authentication/hidpd/AbstractHomeIdpDiscoveryAuthenticatorFactory.java +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/AbstractHomeIdpDiscoveryAuthenticatorFactory.java @@ -90,11 +90,7 @@ public final void close() { @Override public final Map getOperationalInfo() { - String version = getClass().getPackage().getImplementationVersion(); - if (version == null) { - version = "dev-snapshot"; - } - return Map.of("Version", version); + return OperationalInfo.get(); } /** diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/OperationalInfo.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/OperationalInfo.java new file mode 100644 index 0000000..022bc00 --- /dev/null +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/OperationalInfo.java @@ -0,0 +1,15 @@ +package de.sventorben.keycloak.authentication.hidpd; + +import java.util.Map; + +public final class OperationalInfo { + + public static Map get() { + String version = OperationalInfo.class.getPackage().getImplementationVersion(); + if (version == null) { + version = "dev-snapshot"; + } + return Map.of("Version", version); + } + +} diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/DomainExtractor.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/DomainExtractor.java index 41002ec..ca7c963 100644 --- a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/DomainExtractor.java +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/DomainExtractor.java @@ -8,7 +8,6 @@ final class DomainExtractor { private static final Logger LOG = Logger.getLogger(DomainExtractor.class); - private static final String EMAIL_ATTRIBUTE = "email"; private final EmailHomeIdpDiscovererConfig config; @@ -26,11 +25,6 @@ Optional extractFrom(UserModel user) { LOG.warnf("Could not find user attribute '%s' for user '%s'", config.userAttribute(), user.getId()); return Optional.empty(); } - if (EMAIL_ATTRIBUTE.equalsIgnoreCase(config.userAttribute()) && !user.isEmailVerified() - && !config.forwardUserWithUnverifiedEmail()) { - LOG.warnf("Email address of user '%s' is not verified and forwarding not enabled", user.getId()); - return Optional.empty(); - } return extractFrom(userAttribute); } diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/EmailHomeIdpDiscoverer.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/EmailHomeIdpDiscoverer.java index 6645d0e..11c074c 100644 --- a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/EmailHomeIdpDiscoverer.java +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/EmailHomeIdpDiscoverer.java @@ -18,6 +18,7 @@ public final class EmailHomeIdpDiscoverer implements HomeIdpDiscoverer { private static final Logger LOG = Logger.getLogger(EmailHomeIdpDiscoverer.class); + private static final String EMAIL_ATTRIBUTE = "email"; private final Users users; private final IdentityProviders identityProviders; @@ -29,7 +30,6 @@ public EmailHomeIdpDiscoverer(Users users, IdentityProviders identityProviders) @Override public List discoverForUser(AuthenticationFlowContext context, String username) { - EmailHomeIdpDiscovererConfig config = new EmailHomeIdpDiscovererConfig(context.getAuthenticatorConfig()); DomainExtractor domainExtractor = new DomainExtractor(config); @@ -48,7 +48,13 @@ public List discoverForUser(AuthenticationFlowContext con } else { LOG.tracef("User found in AuthenticationFlowContext. Extracting domain from stored user '%s'.", user.getId()); - emailDomain = domainExtractor.extractFrom(user); + if (EMAIL_ATTRIBUTE.equalsIgnoreCase(config.userAttribute()) && !user.isEmailVerified() + && !config.forwardUserWithUnverifiedEmail()) { + LOG.warnf("Email address of user '%s' is not verified and forwarding not enabled", user.getId()); + emailDomain = Optional.empty(); + } else { + emailDomain = domainExtractor.extractFrom(user); + } } if (emailDomain.isPresent()) { @@ -84,7 +90,7 @@ private List discoverHomeIdps(AuthenticationFlowContext c Collectors.toMap(FederatedIdentityModel::getIdentityProvider, FederatedIdentityModel::getUserName)); } - List candidateIdps = identityProviders.candidatesForHomeIdp(context); + List candidateIdps = identityProviders.candidatesForHomeIdp(context, user); if (candidateIdps == null) { candidateIdps = emptyList(); } diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/EmailHomeIdpDiscovererFactory.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/EmailHomeIdpDiscovererFactory.java index 082677c..7b3cc3c 100644 --- a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/EmailHomeIdpDiscovererFactory.java +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/EmailHomeIdpDiscovererFactory.java @@ -1,13 +1,17 @@ package de.sventorben.keycloak.authentication.hidpd.discovery.email; +import de.sventorben.keycloak.authentication.hidpd.OperationalInfo; import de.sventorben.keycloak.authentication.hidpd.Users; import de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscoverer; import de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscovererFactory; import org.keycloak.Config; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.provider.ServerInfoAwareProviderFactory; -public final class EmailHomeIdpDiscovererFactory implements HomeIdpDiscovererFactory { +import java.util.Map; + +public final class EmailHomeIdpDiscovererFactory implements HomeIdpDiscovererFactory, ServerInfoAwareProviderFactory { static final String PROVIDER_ID = "email"; @@ -35,4 +39,9 @@ public void close() { public String getId() { return PROVIDER_ID; } + + @Override + public Map getOperationalInfo() { + return OperationalInfo.get(); + } } diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/IdentityProviders.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/IdentityProviders.java index 137157c..439f7d6 100644 --- a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/IdentityProviders.java +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/email/IdentityProviders.java @@ -5,6 +5,7 @@ import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; import java.util.List; import java.util.stream.Collectors; @@ -50,7 +51,7 @@ public interface IdentityProviders { * current authentication process. * @return A list of {@link IdentityProviderModel} from the realm. May be empty but not {@code null}. */ - default List candidatesForHomeIdp(AuthenticationFlowContext context) { + default List candidatesForHomeIdp(AuthenticationFlowContext context, UserModel user) { RealmModel realm = context.getRealm(); List enabledIdps = realm.getIdentityProvidersStream() .filter(IdentityProviderModel::isEnabled) diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/domainhint/OrgsDomainDiscoverer.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/domainhint/OrgsDomainDiscoverer.java new file mode 100644 index 0000000..7486cce --- /dev/null +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/domainhint/OrgsDomainDiscoverer.java @@ -0,0 +1,44 @@ +package de.sventorben.keycloak.authentication.hidpd.discovery.orgs.domainhint; + +import de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscoverer; +import org.keycloak.authentication.AuthenticationFlowContext; +import org.keycloak.models.IdentityProviderModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.OrganizationModel; +import org.keycloak.organization.OrganizationProvider; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +final class OrgsDomainDiscoverer implements HomeIdpDiscoverer { + + private final KeycloakSession keycloakSession; + + OrgsDomainDiscoverer(KeycloakSession keycloakSession) { + this.keycloakSession = keycloakSession; + } + + @Override + public List discoverForUser(AuthenticationFlowContext context, String username) { + String domain = username; + OrganizationProvider orgProvider = keycloakSession.getProvider(OrganizationProvider.class); + + if (!orgProvider.isEnabled()) { + return Collections.emptyList(); + } + + OrganizationModel org = orgProvider.getByDomainName(domain); + if (org != null) { + return org.getIdentityProviders() + .filter(IdentityProviderModel::isEnabled) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } + + @Override + public void close() { + + } +} diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/domainhint/OrgsDomainDiscovererProviderFactory.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/domainhint/OrgsDomainDiscovererProviderFactory.java new file mode 100644 index 0000000..2309dbc --- /dev/null +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/domainhint/OrgsDomainDiscovererProviderFactory.java @@ -0,0 +1,54 @@ +package de.sventorben.keycloak.authentication.hidpd.discovery.orgs.domainhint; + +import de.sventorben.keycloak.authentication.hidpd.OperationalInfo; +import de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscoverer; +import de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscovererFactory; +import org.keycloak.Config; +import org.keycloak.common.Profile; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.provider.EnvironmentDependentProviderFactory; +import org.keycloak.provider.ServerInfoAwareProviderFactory; + +import java.util.Map; + +public final class OrgsDomainDiscovererProviderFactory implements HomeIdpDiscovererFactory, EnvironmentDependentProviderFactory, ServerInfoAwareProviderFactory { + + static final String PROVIDER_ID = "orgs-domain"; + + @Override + public boolean isSupported(Config.Scope config) { + return Profile.isFeatureEnabled(Profile.Feature.ORGANIZATION); + } + + @Override + public HomeIdpDiscoverer create(KeycloakSession keycloakSession) { + return new OrgsDomainDiscoverer(keycloakSession); + } + + @Override + public void init(Config.Scope scope) { + + } + + @Override + public void postInit(KeycloakSessionFactory keycloakSessionFactory) { + + } + + @Override + public void close() { + + } + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public final Map getOperationalInfo() { + return OperationalInfo.get(); + } + +} diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/domainhint/OrgsDomainHomeIdpDiscoveryAuthenticatorFactory.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/domainhint/OrgsDomainHomeIdpDiscoveryAuthenticatorFactory.java new file mode 100644 index 0000000..6a8c0c0 --- /dev/null +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/domainhint/OrgsDomainHomeIdpDiscoveryAuthenticatorFactory.java @@ -0,0 +1,53 @@ +package de.sventorben.keycloak.authentication.hidpd.discovery.orgs.domainhint; + +import de.sventorben.keycloak.authentication.hidpd.AbstractHomeIdpDiscoveryAuthenticatorFactory; +import org.keycloak.Config; +import org.keycloak.common.Profile; +import org.keycloak.provider.EnvironmentDependentProviderFactory; +import org.keycloak.provider.ProviderConfigProperty; + +import java.util.Collections; +import java.util.List; + +public final class OrgsDomainHomeIdpDiscoveryAuthenticatorFactory extends AbstractHomeIdpDiscoveryAuthenticatorFactory implements EnvironmentDependentProviderFactory { + private static final String PROVIDER_ID = "orgs-domain"; + + @Override + public boolean isSupported(Config.Scope config) { + return Profile.isFeatureEnabled(Profile.Feature.ORGANIZATION); + } + + public OrgsDomainHomeIdpDiscoveryAuthenticatorFactory() { + super(new DiscovererConfig() { + @Override + public List getProperties() { + return Collections.emptyList(); + } + + @Override + public String getProviderId() { + return OrgsDomainDiscovererProviderFactory.PROVIDER_ID; + } + }); + } + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public String getDisplayType() { + return "Home IdP Discovery - Organization via Domain Hint"; + } + + @Override + public String getReferenceCategory() { + return null; + } + + @Override + public String getHelpText() { + return "Redirects users to their organization's identity provider which will be discovered based on a domain hint"; + } +} diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsEmailHomeIdpDiscovererConfig.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsEmailHomeIdpDiscovererConfig.java new file mode 100644 index 0000000..e0de040 --- /dev/null +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsEmailHomeIdpDiscovererConfig.java @@ -0,0 +1,40 @@ +package de.sventorben.keycloak.authentication.hidpd.discovery.orgs.email; + +import org.keycloak.models.AuthenticatorConfigModel; +import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.provider.ProviderConfigurationBuilder; + +import java.util.List; +import java.util.Optional; + +import static org.keycloak.provider.ProviderConfigProperty.BOOLEAN_TYPE; +import static org.keycloak.provider.ProviderConfigProperty.STRING_TYPE; + +final class OrgsEmailHomeIdpDiscovererConfig { + + private static final String FORWARD_UNVERIFIED_ATTRIBUTE = "forwardUnverifiedEmail"; + + private static final ProviderConfigProperty FORWARD_UNVERIFIED_PROPERTY = new ProviderConfigProperty( + FORWARD_UNVERIFIED_ATTRIBUTE, + "Forward users with unverified email", + "If 'User attribute' is set to 'email', whether to forward existing user if user's email is not verified.", + BOOLEAN_TYPE, + false, + false); + + static final List CONFIG_PROPERTIES = ProviderConfigurationBuilder.create() + .property(FORWARD_UNVERIFIED_PROPERTY) + .build(); + private final AuthenticatorConfigModel authenticatorConfigModel; + + public OrgsEmailHomeIdpDiscovererConfig(AuthenticatorConfigModel authenticatorConfigModel) { + this.authenticatorConfigModel = authenticatorConfigModel; + } + + boolean forwardUserWithUnverifiedEmail() { + return Optional.ofNullable(authenticatorConfigModel) + .map(it -> Boolean.parseBoolean(it.getConfig().getOrDefault(FORWARD_UNVERIFIED_ATTRIBUTE, "false"))) + .orElse(false); + } + +} diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsEmailHomeIdpDiscovererFactory.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsEmailHomeIdpDiscovererFactory.java new file mode 100644 index 0000000..3db1799 --- /dev/null +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsEmailHomeIdpDiscovererFactory.java @@ -0,0 +1,48 @@ +package de.sventorben.keycloak.authentication.hidpd.discovery.orgs.email; + +import de.sventorben.keycloak.authentication.hidpd.OperationalInfo; +import de.sventorben.keycloak.authentication.hidpd.Users; +import de.sventorben.keycloak.authentication.hidpd.discovery.email.EmailHomeIdpDiscoverer; +import de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscoverer; +import de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscovererFactory; +import org.keycloak.Config; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.provider.ServerInfoAwareProviderFactory; + +import java.util.Map; + +public final class OrgsEmailHomeIdpDiscovererFactory implements HomeIdpDiscovererFactory, ServerInfoAwareProviderFactory { + + static final String PROVIDER_ID = "orgs-email"; + + @Override + public HomeIdpDiscoverer create(KeycloakSession keycloakSession) { + return new EmailHomeIdpDiscoverer(new Users(keycloakSession), new OrgsIdentityProviders()); + } + + @Override + public void init(Config.Scope scope) { + + } + + @Override + public void postInit(KeycloakSessionFactory keycloakSessionFactory) { + + } + + @Override + public void close() { + + } + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public final Map getOperationalInfo() { + return OperationalInfo.get(); + } +} diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsEmailHomeIdpDiscoveryAuthenticatorFactory.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsEmailHomeIdpDiscoveryAuthenticatorFactory.java new file mode 100644 index 0000000..587592c --- /dev/null +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsEmailHomeIdpDiscoveryAuthenticatorFactory.java @@ -0,0 +1,54 @@ +package de.sventorben.keycloak.authentication.hidpd.discovery.orgs.email; + +import de.sventorben.keycloak.authentication.hidpd.AbstractHomeIdpDiscoveryAuthenticatorFactory; +import org.keycloak.Config; +import org.keycloak.common.Profile; +import org.keycloak.provider.EnvironmentDependentProviderFactory; +import org.keycloak.provider.ProviderConfigProperty; + +import java.util.List; + +public final class OrgsEmailHomeIdpDiscoveryAuthenticatorFactory extends AbstractHomeIdpDiscoveryAuthenticatorFactory implements EnvironmentDependentProviderFactory { + + private static final String PROVIDER_ID = "orgs-email"; + + @Override + public boolean isSupported(Config.Scope config) { + return Profile.isFeatureEnabled(Profile.Feature.ORGANIZATION); + } + + public OrgsEmailHomeIdpDiscoveryAuthenticatorFactory() { + super(new DiscovererConfig() { + @Override + public List getProperties() { + return OrgsEmailHomeIdpDiscovererConfig.CONFIG_PROPERTIES; + } + + @Override + public String getProviderId() { + return PROVIDER_ID; + } + }); + } + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public String getDisplayType() { + return "Home IdP Discovery - Organization via Email"; + } + + @Override + public String getReferenceCategory() { + return null; + } + + @Override + public String getHelpText() { + return "Redirects users to their organization's identity provider which will be discovered based on the domain of the user's email address."; + } + +} diff --git a/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsIdentityProviders.java b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsIdentityProviders.java new file mode 100644 index 0000000..e9375ab --- /dev/null +++ b/src/main/java/de/sventorben/keycloak/authentication/hidpd/discovery/orgs/email/OrgsIdentityProviders.java @@ -0,0 +1,60 @@ +package de.sventorben.keycloak.authentication.hidpd.discovery.orgs.email; + +import de.sventorben.keycloak.authentication.hidpd.discovery.email.Domain; +import de.sventorben.keycloak.authentication.hidpd.discovery.email.IdentityProviders; +import org.keycloak.authentication.AuthenticationFlowContext; +import org.keycloak.models.IdentityProviderModel; +import org.keycloak.models.OrganizationDomainModel; +import org.keycloak.models.OrganizationModel; +import org.keycloak.models.UserModel; +import org.keycloak.organization.OrganizationProvider; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +final class OrgsIdentityProviders implements IdentityProviders { + + @Override + public List candidatesForHomeIdp(AuthenticationFlowContext context, UserModel user) { + OrganizationProvider orgProvider = context.getSession().getProvider(OrganizationProvider.class); + if (user == null) { + return Collections.emptyList(); + } + if (orgProvider.isEnabled()) { + OrganizationModel org = orgProvider.getByMember(user); + if (org != null && org.isEnabled()) { + return org.getIdentityProviders() + .filter(IdentityProviderModel::isEnabled) + .collect(Collectors.toList()); + } + } else { + // TODO: Log a warning + } + return Collections.emptyList(); + } + + @Override + public List withMatchingDomain(AuthenticationFlowContext context, List candidates, Domain domain) { + OrganizationProvider orgProvider = context.getSession().getProvider(OrganizationProvider.class); + if (orgProvider.isEnabled()) { + OrganizationModel org = orgProvider.getByDomainName(domain.getRawValue()); + if (org != null && org.isEnabled()) { + boolean verified = org.getDomains() + .filter(it -> domain.getRawValue().equalsIgnoreCase(it.getName())) + .anyMatch(OrganizationDomainModel::isVerified); + if (verified) { + return org.getIdentityProviders() + .filter(IdentityProviderModel::isEnabled) + // TODO: Filter based on domain - should only be one + .collect(Collectors.toList()); + } + } + } else { + // TODO: Log a warning + } + return Collections.emptyList(); + } + +} diff --git a/src/main/resources/META-INF/services/de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscovererFactory b/src/main/resources/META-INF/services/de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscovererFactory index bb355d9..09aaf87 100644 --- a/src/main/resources/META-INF/services/de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscovererFactory +++ b/src/main/resources/META-INF/services/de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscovererFactory @@ -1 +1,3 @@ de.sventorben.keycloak.authentication.hidpd.discovery.email.EmailHomeIdpDiscovererFactory +de.sventorben.keycloak.authentication.hidpd.discovery.orgs.domainhint.OrgsDomainDiscovererProviderFactory +de.sventorben.keycloak.authentication.hidpd.discovery.orgs.email.OrgsEmailHomeIdpDiscovererFactory diff --git a/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory b/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory index 28772e5..eb4380e 100755 --- a/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory +++ b/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory @@ -1 +1,3 @@ de.sventorben.keycloak.authentication.hidpd.HomeIdpDiscoveryAuthenticatorFactory +de.sventorben.keycloak.authentication.hidpd.discovery.orgs.email.OrgsEmailHomeIdpDiscoveryAuthenticatorFactory +de.sventorben.keycloak.authentication.hidpd.discovery.orgs.domainhint.OrgsDomainHomeIdpDiscoveryAuthenticatorFactory