Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@
<org.snakeyaml.snakeyaml-engine.version>2.6</org.snakeyaml.snakeyaml-engine.version>

<!-- Others -->
<apacheds.version>2.0.0.AM26</apacheds.version>
<apacheds.codec.version>2.0.0</apacheds.codec.version>
<apacheds.version>2.0.0.AM27</apacheds.version>
<apacheds.codec.version>2.1.8</apacheds.codec.version>
<google.zxing.version>3.4.0</google.zxing.version>
<freemarker.version>2.3.32</freemarker.version>
<sundrio.version>0.200.0</sundrio.version>
Expand Down Expand Up @@ -717,10 +717,13 @@
<artifactId>apacheds-server-annotations</artifactId>
<version>${apacheds.version}</version>
</dependency>
<!-- POM import to align all API module versions at 2.1.8. -->
<dependency>
<groupId>org.apache.directory.api</groupId>
<artifactId>api-ldap-codec-standalone</artifactId>
<artifactId>api-parent</artifactId>
<version>${apacheds.codec.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,10 @@ public void usernamePasswordLoginTest() throws Exception {

@Test
public void credentialDelegationTest() throws Exception {
Assume.assumeTrue("Ignoring test as the embedded server is not started", getKerberosRule().isStartEmbeddedLdapServer());
// Credential delegation requires the FORWARDED ticket flag, which Kerby's embedded KDC
// does not support (DIRKRB-458). Skip when using embedded server; run against external KDCs (e.g. MSAD).
Assume.assumeTrue("Credential delegation not supported with embedded Kerby KDC",
!getKerberosRule().isStartEmbeddedLdapServer());
Comment on lines +180 to +181

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True observation but this condition is pre-existing. The invokeLdap method was never designed for external providers. When the internal MSAD pipeline runs the credential delegation test, it would need the LDAP URL/DN adapted. But this isn't something we introduced, it was already the case before our change.

// Add kerberos delegation credential mapper
ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
KerberosConstants.GSS_DELEGATION_CREDENTIAL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,11 @@ public void beforeAbstractKeycloakTest() throws Exception {

getKerberosRule().setKrb5ConfPath(testingClient.testing());

spnegoSchemeFactory = new KeycloakSPNegoSchemeFactory(getKerberosConfig());
// Kerby KDC doesn't set the FORWARDED flag on TGS-REP (DIRKRB-458), causing
// JDK's KrbKdcRep.check() to reject the response with "Message stream modified (41)".
// Disable credential delegation when using the embedded Kerby KDC; external KDCs (e.g. MSAD) support it.
boolean credDelegEnabled = !getKerberosRule().isStartEmbeddedLdapServer();
spnegoSchemeFactory = new KeycloakSPNegoSchemeFactory(getKerberosConfig(), credDelegEnabled);
initHttpClient(true);
removeAllUsers();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,16 @@
public class KeycloakSPNegoSchemeFactory extends SPNegoSchemeFactory {

private final CommonKerberosConfig kerberosConfig;
private final boolean credDelegEnabled;

private String username;
private String password;


public KeycloakSPNegoSchemeFactory(CommonKerberosConfig kerberosConfig) {
public KeycloakSPNegoSchemeFactory(CommonKerberosConfig kerberosConfig, boolean credDelegEnabled) {
super(true, false);
this.kerberosConfig = kerberosConfig;
this.credDelegEnabled = credDelegEnabled;
}


Expand Down Expand Up @@ -121,7 +123,7 @@ public ByteArrayHolder run() throws Exception {
GSSContext gssContext = manager.createContext(
serverName.canonicalize(oid), oid, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestMutualAuth(true);
gssContext.requestCredDeleg(true);
gssContext.requestCredDeleg(credDelegEnabled);
byte[] outputToken = gssContext.initSecContext(token, 0, token.length);

ByteArrayHolder result = new ByteArrayHolder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ objectClass: organizationalUnit
objectClass: top
ou: People

# Kerby's LdapIdentityGetHelper requires krb5AccountDisabled, krb5AccountLockedOut,
# krb5AccountExpirationTime, and krb5KDCFlags on each entry — NPEs without them.
dn: uid=krbtgt,ou=People,dc=kc2,dc=com
objectClass: top
objectClass: person
Expand All @@ -21,6 +23,10 @@ uid: krbtgt
userPassword: secret
krb5PrincipalName: krbtgt/KC2.COM@KC2.COM
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

# Cross-realm trust support! Realm KEYCLOAK.ORG will trust the realm KC2.COM
dn: uid=krbtgt2,ou=People,dc=kc2,dc=com
Expand All @@ -35,6 +41,10 @@ uid: krbtgt2
userPassword: secret
krb5PrincipalName: krbtgt/KEYCLOAK.ORG@KC2.COM
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=ldap,ou=People,dc=kc2,dc=com
objectClass: top
Expand All @@ -48,6 +58,10 @@ uid: ldap
userPassword: randall
krb5PrincipalName: ${ldapSaslPrincipal}
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=HTTP,ou=People,dc=kc2,dc=com
objectClass: top
Expand All @@ -61,6 +75,10 @@ uid: HTTP
userPassword: httppwd
krb5PrincipalName: HTTP/${hostname}@KC2.COM
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=hnelson2,ou=People,dc=kc2,dc=com
objectClass: top
Expand All @@ -75,6 +93,10 @@ uid: hnelson2
userPassword: secret
krb5PrincipalName: hnelson2@KC2.COM
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=jduke,ou=People,dc=kc2,dc=com
objectClass: top
Expand All @@ -89,6 +111,10 @@ uid: jduke
userPassword: theduke
krb5PrincipalName: jdukekeycloak@KC2.COM
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=jduke2,ou=People,dc=kc2,dc=com
objectClass: top
Expand All @@ -103,6 +129,10 @@ uid: jduke2
userPassword: theduke2
krb5PrincipalName: jduke@KC2.COM
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=gsstestserver,ou=People,dc=kc2,dc=com
objectClass: top
Expand All @@ -116,3 +146,7 @@ uid: gsstestserver
userPassword: gsstestpwd
krb5PrincipalName: gsstestserver/xxx@KC2.COM
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ objectClass: organizationalUnit
objectClass: top
ou: People

# Kerby's LdapIdentityGetHelper requires krb5AccountDisabled, krb5AccountLockedOut,
# krb5AccountExpirationTime, and krb5KDCFlags on each entry — NPEs without them.
dn: uid=krbtgt,ou=People,dc=keycloak,dc=org
objectClass: top
objectClass: person
Expand All @@ -21,6 +23,10 @@ uid: krbtgt
userPassword: secret
krb5PrincipalName: krbtgt/KEYCLOAK.ORG@KEYCLOAK.ORG
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

# Cross-realm trust support! Realm KEYCLOAK.ORG will trust the realm KC2.COM
dn: uid=krbtgt2,ou=People,dc=keycloak,dc=org
Expand All @@ -35,6 +41,10 @@ uid: krbtgt2
userPassword: secret
krb5PrincipalName: krbtgt/KEYCLOAK.ORG@KC2.COM
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=ldap,ou=People,dc=keycloak,dc=org
objectClass: top
Expand All @@ -48,6 +58,10 @@ uid: ldap
userPassword: randall
krb5PrincipalName: ${ldapSaslPrincipal}
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=HTTP,ou=People,dc=keycloak,dc=org
objectClass: top
Expand All @@ -61,6 +75,10 @@ uid: HTTP
userPassword: httppwd
krb5PrincipalName: HTTP/${hostname}@KEYCLOAK.ORG
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=hnelson,ou=People,dc=keycloak,dc=org
objectClass: top
Expand All @@ -75,6 +93,10 @@ uid: hnelson
userPassword: secret
krb5PrincipalName: hnelson@KEYCLOAK.ORG
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=jduke,ou=People,dc=keycloak,dc=org
objectClass: top
Expand All @@ -89,6 +111,10 @@ uid: jduke
userPassword: theduke
krb5PrincipalName: jduke@KEYCLOAK.ORG
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=MyDuke,ou=People,dc=keycloak,dc=org
objectClass: top
Expand All @@ -103,6 +129,10 @@ uid: MyDuke
userPassword: theduke
krb5PrincipalName: MyDuke@KEYCLOAK.ORG
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126

dn: uid=gsstestserver,ou=People,dc=keycloak,dc=org
objectClass: top
Expand All @@ -116,3 +146,7 @@ uid: gsstestserver
userPassword: gsstestpwd
krb5PrincipalName: gsstestserver/xxx@KEYCLOAK.ORG
krb5KeyVersionNumber: 0
krb5AccountDisabled: FALSE
krb5AccountLockedOut: FALSE
krb5AccountExpirationTime: 99991231235959Z
krb5KDCFlags: 126
12 changes: 11 additions & 1 deletion testsuite/utils/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,21 @@
<scope>compile</scope>
</dependency>

<!-- Apache DS -->
<!-- Apache DS for embedded LDAP, Apache Kerby for KDC (AM27 removed apacheds-protocol-kerberos) -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-util-embedded-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.apache.kerby</groupId>
<artifactId>kerb-simplekdc</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.kerby</groupId>
<artifactId>ldap-backend</artifactId>
<version>2.1.0</version>
</dependency>

<dependency>
<groupId>${ee.maven.groupId}</groupId>
Expand Down
Loading
Loading