Skip to content

Commit 89c165e

Browse files
committed
#235 Implement own authenticator base on HomeIdp discovery
Use some tricks
1 parent 7fbd0cc commit 89c165e

File tree

47 files changed

+172
-1981
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+172
-1981
lines changed

Diff for: lib/keycloak-home-idp-discovery.jar

63.6 KB
Binary file not shown.

Diff for: pom.xml

+7
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,13 @@
259259
<version>3.5.3</version>
260260
<optional>true</optional>
261261
</dependency>
262+
<dependency>
263+
<groupId>de.sventorben.keycloak</groupId>
264+
<artifactId>keycloak-home-idp-discovery</artifactId>
265+
<version>25.0.0</version>
266+
<scope>system</scope>
267+
<systemPath>${project.basedir}/lib/keycloak-home-idp-discovery.jar</systemPath>
268+
</dependency>
262269

263270
<!-- testing -->
264271
<dependency>

Diff for: src/main/java/io/phasetwo/service/auth/idp/discovery/email/EmailHomeIdpDiscovererConfig.java renamed to src/main/java/de/sventorben/keycloak/authentication/hidpd/OrgsEmailHomeIdpDiscovererConfig.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
//package io.phasetwo.service.auth.idp.discovery.email;
2-
package io.phasetwo.service.auth.idp.discovery.email;
1+
package de.sventorben.keycloak.authentication.hidpd;
32

43
import org.keycloak.models.AuthenticatorConfigModel;
54
import org.keycloak.provider.ProviderConfigProperty;
@@ -11,7 +10,7 @@
1110
import static org.keycloak.provider.ProviderConfigProperty.BOOLEAN_TYPE;
1211
import static org.keycloak.provider.ProviderConfigProperty.STRING_TYPE;
1312

14-
final class EmailHomeIdpDiscovererConfig {
13+
final class OrgsEmailHomeIdpDiscovererConfig {
1514

1615
private static final String FORWARD_TO_LINKED_IDP = "forwardToLinkedIdp";
1716
private static final String USER_ATTRIBUTE = "userAttribute";
@@ -58,7 +57,7 @@ final class EmailHomeIdpDiscovererConfig {
5857
.build();
5958
private final AuthenticatorConfigModel authenticatorConfigModel;
6059

61-
public EmailHomeIdpDiscovererConfig(AuthenticatorConfigModel authenticatorConfigModel) {
60+
public OrgsEmailHomeIdpDiscovererConfig(AuthenticatorConfigModel authenticatorConfigModel) {
6261
this.authenticatorConfigModel = authenticatorConfigModel;
6362
}
6463

Diff for: src/main/java/io/phasetwo/service/auth/idp/discovery/orgs/email/OrgsEmailHomeIdpDiscovererFactory.java renamed to src/main/java/de/sventorben/keycloak/authentication/hidpd/OrgsEmailHomeIdpDiscovererFactory.java

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
//package io.phasetwo.service.auth.idp.discovery.orgs.email;
2-
package io.phasetwo.service.auth.idp.discovery.orgs.email;
1+
package de.sventorben.keycloak.authentication.hidpd;
32

43
import com.google.auto.service.AutoService;
5-
import io.phasetwo.service.auth.idp.OperationalInfo;
6-
import io.phasetwo.service.auth.idp.Users;
7-
import io.phasetwo.service.auth.idp.discovery.email.EmailHomeIdpDiscoverer;
8-
import io.phasetwo.service.auth.idp.discovery.spi.HomeIdpDiscoverer;
4+
import de.sventorben.keycloak.authentication.hidpd.discovery.email.EmailHomeIdpDiscoverer;
5+
import de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscoverer;
6+
import de.sventorben.keycloak.authentication.hidpd.discovery.spi.HomeIdpDiscovererFactory;
97
import org.keycloak.Config;
108
import org.keycloak.models.KeycloakSession;
119
import org.keycloak.models.KeycloakSessionFactory;
1210
import org.keycloak.provider.ServerInfoAwareProviderFactory;
1311

1412
import java.util.Map;
15-
import io.phasetwo.service.auth.idp.discovery.spi.HomeIdpDiscovererFactory;
1613

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

20-
static final String PROVIDER_ID = "orgs-email";
17+
static final String PROVIDER_ID = "orgs-ext-email";
2118

2219
@Override
2320
public HomeIdpDiscoverer create(KeycloakSession keycloakSession) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package de.sventorben.keycloak.authentication.hidpd;
2+
3+
import de.sventorben.keycloak.authentication.hidpd.discovery.email.Domain;
4+
import de.sventorben.keycloak.authentication.hidpd.discovery.email.IdentityProviders;
5+
import io.phasetwo.service.model.OrganizationModel;
6+
import io.phasetwo.service.model.OrganizationProvider;
7+
import org.keycloak.authentication.AuthenticationFlowContext;
8+
import org.keycloak.models.IdentityProviderModel;
9+
10+
import java.util.List;
11+
import java.util.stream.Collectors;
12+
13+
final class OrgsIdentityProviders implements IdentityProviders {
14+
15+
@Override
16+
public List<IdentityProviderModel> withMatchingDomain(AuthenticationFlowContext context, List<IdentityProviderModel> candidates, Domain domain) {
17+
var orgs = context.getSession().getProvider(OrganizationProvider.class);
18+
var config = new OrgsEmailHomeIdpDiscovererConfig(context.getAuthenticatorConfig());
19+
return orgs.getOrganizationsStreamForDomain(
20+
context.getRealm(), domain.toString(), config.requireVerifiedDomain())
21+
.flatMap(OrganizationModel::getIdentityProvidersStream)
22+
.filter(IdentityProviderModel::isEnabled)
23+
.collect(Collectors.toList());
24+
}
25+
}

Diff for: src/main/java/io/phasetwo/service/auth/idp/HomeIdpDiscoveryAuthenticator.java renamed to src/main/java/de/sventorben/keycloak/authentication/hidpd/PhaseTwoAuthenticator.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
//package de.sventorben.keycloak.authentication.hidpd;
2-
package io.phasetwo.service.auth.idp;
1+
package de.sventorben.keycloak.authentication.hidpd;
32

43
import jakarta.ws.rs.core.MultivaluedMap;
54
import jakarta.ws.rs.core.Response;
@@ -24,13 +23,13 @@
2423
import static org.keycloak.protocol.oidc.OIDCLoginProtocol.LOGIN_HINT_PARAM;
2524
import static org.keycloak.services.validation.Validation.FIELD_USERNAME;
2625

27-
final class HomeIdpDiscoveryAuthenticator extends AbstractUsernameFormAuthenticator {
26+
final class PhaseTwoAuthenticator extends AbstractUsernameFormAuthenticator {
2827

29-
private static final Logger LOG = Logger.getLogger(HomeIdpDiscoveryAuthenticator.class);
28+
private static final Logger LOG = Logger.getLogger(PhaseTwoAuthenticator.class);
3029

3130
private final AbstractHomeIdpDiscoveryAuthenticatorFactory.DiscovererConfig discovererConfig;
3231

33-
HomeIdpDiscoveryAuthenticator(AbstractHomeIdpDiscoveryAuthenticatorFactory.DiscovererConfig discovererConfig) {
32+
PhaseTwoAuthenticator(AbstractHomeIdpDiscoveryAuthenticatorFactory.DiscovererConfig discovererConfig) {
3433
this.discovererConfig = discovererConfig;
3534
}
3635

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package de.sventorben.keycloak.authentication.hidpd;
2+
3+
import com.google.auto.service.AutoService;
4+
import org.keycloak.Config;
5+
import org.keycloak.authentication.Authenticator;
6+
import org.keycloak.authentication.AuthenticatorFactory;
7+
import org.keycloak.models.AuthenticationExecutionModel;
8+
import org.keycloak.models.KeycloakSession;
9+
import org.keycloak.models.KeycloakSessionFactory;
10+
import org.keycloak.provider.ProviderConfigProperty;
11+
import org.keycloak.provider.ServerInfoAwareProviderFactory;
12+
13+
import java.util.List;
14+
import java.util.Map;
15+
import java.util.stream.Collectors;
16+
import java.util.stream.Stream;
17+
18+
import static org.keycloak.models.AuthenticationExecutionModel.Requirement.ALTERNATIVE;
19+
import static org.keycloak.models.AuthenticationExecutionModel.Requirement.DISABLED;
20+
import static org.keycloak.models.AuthenticationExecutionModel.Requirement.REQUIRED;
21+
22+
@AutoService(AuthenticatorFactory.class)
23+
public final class PhaseTwoAuthenticatorFactory implements AuthenticatorFactory, ServerInfoAwareProviderFactory {
24+
25+
private static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = new AuthenticationExecutionModel.Requirement[]{REQUIRED, ALTERNATIVE, DISABLED};
26+
27+
private static final String PROVIDER_ID = "ext-auth-home-idp-discovery";
28+
29+
public Authenticator create(KeycloakSession session) {
30+
31+
//@xpg -this could be simplified if we could convince the HomeIDPProvider guy to remove final from the creation phase
32+
// public final Authenticator create(KeycloakSession session) {
33+
// return new HomeIdpDiscoveryAuthenticator(discovererConfig);
34+
// }
35+
return new PhaseTwoAuthenticator(new AbstractHomeIdpDiscoveryAuthenticatorFactory.DiscovererConfig() {
36+
public List<ProviderConfigProperty> getProperties() {
37+
return OrgsEmailHomeIdpDiscovererConfig.CONFIG_PROPERTIES;
38+
}
39+
40+
public String getProviderId() {
41+
return "orgs-ext-email";
42+
}
43+
});
44+
}
45+
46+
@Override
47+
public String getDisplayType() {
48+
return "PhaseTwo Home IdP Discovery";
49+
}
50+
51+
@Override
52+
public String getReferenceCategory() {
53+
return "Authorization";
54+
}
55+
56+
@Override
57+
public boolean isConfigurable() {
58+
return true;
59+
}
60+
61+
@Override
62+
public final AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
63+
return REQUIREMENT_CHOICES;
64+
}
65+
66+
@Override
67+
public boolean isUserSetupAllowed() {
68+
return false;
69+
}
70+
71+
@Override
72+
public String getHelpText() {
73+
return "Redirects users to their home identity provider";
74+
}
75+
76+
@Override
77+
public final List<ProviderConfigProperty> getConfigProperties() {
78+
return Stream.concat(
79+
HomeIdpForwarderConfigProperties.CONFIG_PROPERTIES.stream(),
80+
OrgsEmailHomeIdpDiscovererConfig.CONFIG_PROPERTIES.stream())
81+
.collect(Collectors.toList());
82+
}
83+
84+
@Override
85+
public String getId() {
86+
return PROVIDER_ID;
87+
}
88+
89+
@Override
90+
public Map<String, String> getOperationalInfo() {
91+
return OperationalInfo.get();
92+
}
93+
94+
95+
@Override
96+
public void init(Config.Scope scope) {
97+
98+
}
99+
100+
@Override
101+
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
102+
103+
}
104+
105+
@Override
106+
public void close() {
107+
108+
}
109+
}
110+

Diff for: src/main/java/io/phasetwo/service/auth/idp/AbstractHomeIdpDiscoveryAuthenticatorFactory.java

-134
This file was deleted.

Diff for: src/main/java/io/phasetwo/service/auth/idp/AlwaysSelectableIdentityProviderModel.java

-27
This file was deleted.

0 commit comments

Comments
 (0)