Skip to content

Commit

Permalink
p2-inc#235 Implement own authenticator base on HomeIdp discovery
Browse files Browse the repository at this point in the history
Use some tricks
  • Loading branch information
rtufisi committed Jul 27, 2024
1 parent 7fbd0cc commit ac4113b
Show file tree
Hide file tree
Showing 47 changed files with 172 additions and 1,981 deletions.
Binary file added lib/keycloak-home-idp-discovery.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,13 @@
<version>3.5.3</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>de.sventorben.keycloak</groupId>
<artifactId>keycloak-home-idp-discovery</artifactId>
<version>25.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/keycloak-home-idp-discovery.jar</systemPath>
</dependency>

<!-- testing -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//package io.phasetwo.service.auth.idp.discovery.email;
package io.phasetwo.service.auth.idp.discovery.email;
package de.sventorben.keycloak.authentication.hidpd;

import org.keycloak.models.AuthenticatorConfigModel;
import org.keycloak.provider.ProviderConfigProperty;
Expand All @@ -11,7 +10,7 @@
import static org.keycloak.provider.ProviderConfigProperty.BOOLEAN_TYPE;
import static org.keycloak.provider.ProviderConfigProperty.STRING_TYPE;

final class EmailHomeIdpDiscovererConfig {
final class OrgsEmailHomeIdpDiscovererConfig {

private static final String FORWARD_TO_LINKED_IDP = "forwardToLinkedIdp";
private static final String USER_ATTRIBUTE = "userAttribute";
Expand Down Expand Up @@ -58,7 +57,7 @@ final class EmailHomeIdpDiscovererConfig {
.build();
private final AuthenticatorConfigModel authenticatorConfigModel;

public EmailHomeIdpDiscovererConfig(AuthenticatorConfigModel authenticatorConfigModel) {
public OrgsEmailHomeIdpDiscovererConfig(AuthenticatorConfigModel authenticatorConfigModel) {
this.authenticatorConfigModel = authenticatorConfigModel;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
//package io.phasetwo.service.auth.idp.discovery.orgs.email;
package io.phasetwo.service.auth.idp.discovery.orgs.email;
package de.sventorben.keycloak.authentication.hidpd;

import com.google.auto.service.AutoService;
import io.phasetwo.service.auth.idp.OperationalInfo;
import io.phasetwo.service.auth.idp.Users;
import io.phasetwo.service.auth.idp.discovery.email.EmailHomeIdpDiscoverer;
import io.phasetwo.service.auth.idp.discovery.spi.HomeIdpDiscoverer;
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;
import io.phasetwo.service.auth.idp.discovery.spi.HomeIdpDiscovererFactory;

@AutoService(HomeIdpDiscovererFactory.class)
public final class OrgsEmailHomeIdpDiscovererFactory implements HomeIdpDiscovererFactory, ServerInfoAwareProviderFactory {

static final String PROVIDER_ID = "orgs-email";
static final String PROVIDER_ID = "orgs-ext-email";

@Override
public HomeIdpDiscoverer create(KeycloakSession keycloakSession) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package de.sventorben.keycloak.authentication.hidpd;

import de.sventorben.keycloak.authentication.hidpd.discovery.email.Domain;
import de.sventorben.keycloak.authentication.hidpd.discovery.email.IdentityProviders;
import io.phasetwo.service.model.OrganizationModel;
import io.phasetwo.service.model.OrganizationProvider;
import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.models.IdentityProviderModel;

import java.util.List;
import java.util.stream.Collectors;

final class OrgsIdentityProviders implements IdentityProviders {

@Override
public List<IdentityProviderModel> withMatchingDomain(AuthenticationFlowContext context, List<IdentityProviderModel> candidates, Domain domain) {
var orgs = context.getSession().getProvider(OrganizationProvider.class);
var config = new OrgsEmailHomeIdpDiscovererConfig(context.getAuthenticatorConfig());
return orgs.getOrganizationsStreamForDomain(
context.getRealm(), domain.toString(), config.requireVerifiedDomain())
.flatMap(OrganizationModel::getIdentityProvidersStream)
.filter(IdentityProviderModel::isEnabled)
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//package de.sventorben.keycloak.authentication.hidpd;
package io.phasetwo.service.auth.idp;
package de.sventorben.keycloak.authentication.hidpd;

import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
Expand All @@ -24,13 +23,13 @@
import static org.keycloak.protocol.oidc.OIDCLoginProtocol.LOGIN_HINT_PARAM;
import static org.keycloak.services.validation.Validation.FIELD_USERNAME;

final class HomeIdpDiscoveryAuthenticator extends AbstractUsernameFormAuthenticator {
final class PhaseTwoAuthenticator extends AbstractUsernameFormAuthenticator {

private static final Logger LOG = Logger.getLogger(HomeIdpDiscoveryAuthenticator.class);
private static final Logger LOG = Logger.getLogger(PhaseTwoAuthenticator.class);

private final AbstractHomeIdpDiscoveryAuthenticatorFactory.DiscovererConfig discovererConfig;

HomeIdpDiscoveryAuthenticator(AbstractHomeIdpDiscoveryAuthenticatorFactory.DiscovererConfig discovererConfig) {
PhaseTwoAuthenticator(AbstractHomeIdpDiscoveryAuthenticatorFactory.DiscovererConfig discovererConfig) {
this.discovererConfig = discovererConfig;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package de.sventorben.keycloak.authentication.hidpd;

import com.google.auto.service.AutoService;
import org.keycloak.Config;
import org.keycloak.authentication.Authenticator;
import org.keycloak.authentication.AuthenticatorFactory;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ServerInfoAwareProviderFactory;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.keycloak.models.AuthenticationExecutionModel.Requirement.ALTERNATIVE;
import static org.keycloak.models.AuthenticationExecutionModel.Requirement.DISABLED;
import static org.keycloak.models.AuthenticationExecutionModel.Requirement.REQUIRED;

@AutoService(AuthenticatorFactory.class)
public final class PhaseTwoAuthenticatorFactory implements AuthenticatorFactory, ServerInfoAwareProviderFactory {

private static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = new AuthenticationExecutionModel.Requirement[]{REQUIRED, ALTERNATIVE, DISABLED};

private static final String PROVIDER_ID = "ext-auth-home-idp-discovery";

public Authenticator create(KeycloakSession session) {

//@xpg -this could be simplified if we could convince the HomeIDPProvider guy to remove final from the creation phase
// public final Authenticator create(KeycloakSession session) {
// return new HomeIdpDiscoveryAuthenticator(discovererConfig);
// }
return new PhaseTwoAuthenticator(new AbstractHomeIdpDiscoveryAuthenticatorFactory.DiscovererConfig() {
public List<ProviderConfigProperty> getProperties() {
return OrgsEmailHomeIdpDiscovererConfig.CONFIG_PROPERTIES;
}

public String getProviderId() {
return "orgs-ext-email";
}
});
}

@Override
public String getDisplayType() {
return "PhaseTwo Home IdP Discovery";
}

@Override
public String getReferenceCategory() {
return "Authorization";
}

@Override
public boolean isConfigurable() {
return true;
}

@Override
public final AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
return REQUIREMENT_CHOICES;
}

@Override
public boolean isUserSetupAllowed() {
return false;
}

@Override
public String getHelpText() {
return "Redirects users to their home identity provider";
}

@Override
public final List<ProviderConfigProperty> getConfigProperties() {
return Stream.concat(
HomeIdpForwarderConfigProperties.CONFIG_PROPERTIES.stream(),
OrgsEmailHomeIdpDiscovererConfig.CONFIG_PROPERTIES.stream())
.collect(Collectors.toList());
}

@Override
public String getId() {
return PROVIDER_ID;
}

@Override
public Map<String, String> getOperationalInfo() {
return Map.of();
}


@Override
public void init(Config.Scope scope) {

}

@Override
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {

}

@Override
public void close() {

}
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit ac4113b

Please sign in to comment.