Repository navigation
Migrate OIDC client-authentication and sub-mismatch broker tests - #52376
Conversation
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Migrates 8 OIDC broker client-authentication and sub-mismatch introspection tests from legacy Arquillian to the JUnit 5-based test framework, relocating them under tests/base/.../broker/oidc/, and factors shared provider-realm setup into AbstractKcOidcBrokerTest (including a fix to endpoint rewriting for non-default provider client IDs).
Changes:
- Moved 8 legacy broker OIDC tests to the new
tests/baseJUnit 5 framework and removed the legacy versions. - Refactored shared provider realm/client scaffolding into
AbstractKcOidcBrokerTestviacreateDefaultProviderClient()andconfigureProviderRealm(...). - Fixed
configureBrokerEndpoints()to locate the provider-side client via a placeholder redirect URI instead of a fixed clientId.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerSubMatchIntrospectionTest.java | Removes legacy Arquillian version of the test. |
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerPrivateKeyJwtWithX509HeadersTest.java | Removes legacy Arquillian version of the test. |
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerPrivateKeyJwtTest.java | Removes legacy Arquillian version of the test. |
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerPrivateKeyJwtCustomSignAlgTest.java | Removes legacy Arquillian version of the test. |
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerPrivateKeyJwtCustomAudienceTest.java | Removes legacy Arquillian version of the test. |
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerColonAliasClientSecretBasicAuthTest.java | Removes legacy Arquillian version of the test. |
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerClientSecretJwtTest.java | Removes legacy Arquillian version of the test. |
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerClientSecretJwtCustomSignAlgTest.java | Removes legacy Arquillian version of the test. |
| tests/base/src/test/java/org/keycloak/tests/broker/oidc/KcOidcBrokerSubMatchIntrospectionTest.java | Adds migrated JUnit 5 test with provider realm config and disabled inherited test. |
| tests/base/src/test/java/org/keycloak/tests/broker/oidc/KcOidcBrokerPrivateKeyJwtWithX509HeadersTest.java | Adds migrated JUnit 5 test using shared provider realm config and custom consumer config. |
| tests/base/src/test/java/org/keycloak/tests/broker/oidc/KcOidcBrokerPrivateKeyJwtTest.java | Adds migrated JUnit 5 baseline private_key_jwt test and reusable provider realm config. |
| tests/base/src/test/java/org/keycloak/tests/broker/oidc/KcOidcBrokerPrivateKeyJwtCustomSignAlgTest.java | Adds migrated JUnit 5 test that provisions an ECDSA key provider and configures signing alg. |
| tests/base/src/test/java/org/keycloak/tests/broker/oidc/KcOidcBrokerPrivateKeyJwtCustomAudienceTest.java | Adds migrated JUnit 5 test overriding client assertion audience on the IdP config. |
| tests/base/src/test/java/org/keycloak/tests/broker/oidc/KcOidcBrokerColonAliasClientSecretBasicAuthTest.java | Adds migrated JUnit 5 test ensuring non-default provider client IDs work end-to-end. |
| tests/base/src/test/java/org/keycloak/tests/broker/oidc/KcOidcBrokerClientSecretJwtTest.java | Adds migrated JUnit 5 client-secret-jwt test wiring provider and consumer realms. |
| tests/base/src/test/java/org/keycloak/tests/broker/oidc/KcOidcBrokerClientSecretJwtCustomSignAlgTest.java | Adds migrated JUnit 5 client-secret-jwt custom signing-alg test. |
| tests/base/src/test/java/org/keycloak/tests/broker/AbstractKcOidcBrokerTest.java | Refactors shared provider realm/client setup and adjusts endpoint rewrite lookup logic. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
973b06f to
1abfd43
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
The subject-mismatch test bypasses reusable endpoint configuration and remains tied to a hard-coded server URL.
Review details
Suppressed comments (1)
tests/base/src/test/java/org/keycloak/tests/broker/oidc/KcOidcBrokerSu 8000 bMatchIntrospectionTest.java:62
- This bare client no longer carries the default admin URL/backchannel-logout attributes, and its redirect URI does not match the placeholder that
configureBrokerEndpoints()rewrites. The test therefore only works with the hard-coded localhost realm URL; build fromcreateDefaultProviderClient()and add the sub mapper so alternate server URLs and the migrated client configuration remain covered.
.clients(ClientBuilder.create(CLIENT_ID)
.secret(CLIENT_SECRET)
.redirectUris("http://localhost:8080/realms/" + CONSUMER_REALM
+ "/broker/" + IDP_OIDC_ALIAS + "/endpoint/*")
- Files reviewed: 17/17 changed files
- Comments generated: 0 new
- Review effort level: Balanced
1abfd43 to
8acd742
Compare
Migrate KcOidcBrokerIdpHintTest (4 own tests), KcOidcBrokerHiddenIdpHintTest (1 own test), and KcOidcBrokerNonceParameterTest (2 own tests, including a new testNonceSet that verifies the nonce is present in the token response - legacy only had testNonceNotSet). Adapted to the merged abstract-class baseline: concrete classes extend AbstractKcOidcBrokerTest instead of implementing KcOidcBrokerConfigSupport directly (the phase-2 branch deliberately skipped BrokerLoginTest here since these classes bring their own @test methods and didn't want the generic login tests as extra, possibly-conflicting coverage). The current abstract hierarchy bakes testLogInAsUserInIDP()/testLoginWithExistingUser() into AbstractBrokerLoginTest, which AbstractKcOidcBrokerTest always extends, so there's no way to pull in just the OIDC config layer without them: - KcOidcBrokerIdpHintTest and KcOidcBrokerNonceParameterTest use configs compatible with the inherited login tests (default or purely additive), so they run as harmless extra coverage. - KcOidcBrokerHiddenIdpHintTest's IDP is hidden from the login page, which would break the inherited tests' logInWithBroker() (clicks a social button that isn't rendered) - overridden and @disabled with a reason, mirroring the existing KcOidcBrokerSubMatchIntrospectionTest pattern, rather than restructuring the shared hierarchy for one test class. Added AbstractBrokerTest.disableUpdateProfileOnFirstLogin(): both nonce tests need to skip the first-broker-login review-profile interruption to test the nonce flow directly. Not present in the merged base (a phase-1 ripple fix that predates the abstract-class rework); re-added here in the form the phase-2 branch already converged on the phase-1 fix (disables both the review-profile flow step and the consumer's VERIFY_PROFILE required action, mirroring the legacy suite which never enabled VERIFY_PROFILE). Also carries forward two fixes independently re-derived per batch since this branch is off upstream/main: createOidcIdentityProvider()/ configureConsumerRealm() widened to protected (oidc/ subpackage cross-package access, same as keycloak#52372/keycloak#52376), and the configureBrokerEndpoints() provider- client lookup fixed to match by placeholder redirect URI instead of the fixed CLIENT_ID (same fix as keycloak#52376). Closes keycloak#52244 Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
There was a problem hiding this comment.
🟡 Changes recommended
Hard-coded JWKS and assertion-audience URLs break migrated tests under non-default server URLs.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 17/17 changed files
- Comments generated: 3
- Review effort level: Balanced
| .attribute("clientAssertionAudience", | ||
| "http://localhost:8080/realms/" + PROVIDER_REALM)); |
| .attribute(OIDCConfigAttributes.USE_JWKS_URL, "true") | ||
| .attribute(OIDCConfigAttributes.JWKS_URL, | ||
| "http://localhost:8080/realms/" + CONSUMER_REALM + "/protocol/openid-connect/certs") |
| .attribute(OIDCConfigAttributes.USE_JWKS_URL, "true") | ||
| .attribute(OIDCConfigAttributes.JWKS_URL, | ||
| "http://localhost:8080/realms/" + CONSUMER_REALM + "/protocol/openid-connect/certs")); |
8acd742 to
b36b125
Compare
Migrate KcOidcBrokerIdpHintTest (4 own tests), KcOidcBrokerHiddenIdpHintTest (1 own test), and KcOidcBrokerNonceParameterTest (2 own tests, including a new testNonceSet that verifies the nonce is present in the token response - legacy only had testNonceNotSet). Adapted to the merged abstract-class baseline: concrete classes extend AbstractKcOidcBrokerTest instead of implementing KcOidcBrokerConfigSupport directly (the phase-2 branch deliberately skipped BrokerLoginTest here since these classes bring their own @test methods and didn't want the generic login tests as extra, possibly-conflicting coverage). The current abstract hierarchy bakes testLogInAsUserInIDP()/testLoginWithExistingUser() into AbstractBrokerLoginTest, which AbstractKcOidcBrokerTest always extends, so there's no way to pull in just the OIDC config layer without them: - KcOidcBrokerIdpHintTest and KcOidcBrokerNonceParameterTest use configs compatible with the inherited login tests (default or purely additive), so they run as harmless extra coverage. - KcOidcBrokerHiddenIdpHintTest's IDP is hidden from the login page, which would break the inherited tests' logInWithBroker() (clicks a social button that isn't rendered) - overridden and @disabled with a reason, mirroring the existing KcOidcBrokerSubMatchIntrospectionTest pattern, rather than restructuring the shared hierarchy for one test class. Added AbstractBrokerTest.disableUpdateProfileOnFirstLogin(): both nonce tests need to skip the first-broker-login review-profile interruption to test the nonce flow directly. Not present in the merged base (a phase-1 ripple fix that predates the abstract-class rework); re-added here in the form the phase-2 branch already converged on the phase-1 fix (disables both the review-profile flow step and the consumer's VERIFY_PROFILE required action, mirroring the legacy suite which never enabled VERIFY_PROFILE). Also carries forward two fixes independently re-derived per batch since this branch is off upstream/main: createOidcIdentityProvider()/ configureConsumerRealm() widened to protected (oidc/ subpackage cross-package access, same as #52372/#52376), and the configureBrokerEndpoints() provider- client lookup fixed to match by placeholder redirect URI instead of the fixed CLIENT_ID (same fix as #52376). Closes #52244 Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
There was a problem hiding this comment.
🟢 Approval recommended
The migrated scenarios preserve their intended coverage, and the shared endpoint fix supports customized client IDs without regressing the default path.
Review details
- Files reviewed: 17/17 changed files
- Comments generated: 0 new
- Review effort level: Balanced
…te oidc package Pure git rename of the eight legacy client-secret-jwt, private-key-jwt, and sub-mismatch broker tests into the new testsuite oidc package. No content changes; the new-testsuite adaptation follows in the next commit. Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
b36b125 to
1a2fc14
Compare
There was a problem hiding this comment.
🟢 Approval recommended
The migration preserves the covered scenarios, integrates cleanly with the shared test framework, and reports focused passing tests.
Review details
- Files reviewed: 17/17 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Migrate KcOidcBrokerClientSecretJwtTest, KcOidcBrokerClientSecretJwtCustomSignAlgTest, KcOidcBrokerColonAliasClientSecretBasicAuthTest, KcOidcBrokerPrivateKeyJwtTest, KcOidcBrokerPrivateKeyJwtCustomSignAlgTest, KcOidcBrokerPrivateKeyJwtCustomAudienceTest, KcOidcBrokerPrivateKeyJwtWithX509HeadersTest, and KcOidcBrokerSubMatchIntrospectionTest. Config-only variants except KcOidcBrokerSubMatchIntrospectionTest, which overrides testLogInAsUserInIDP and disables testLoginWithExistingUser (renamed from loginWithExistingUser per phase-1's 2nd review round - the base method was renamed and any override must follow or it silently detaches into a non-@test method). Adapted to the merged abstract-class baseline: concrete classes extend AbstractKcOidcBrokerTest instead of implementing BrokerLoginTest + KcOidcBrokerConfigSupport, dropping the oauth/webDriver/loginPage/ updateProfilePage getter boilerplate and the realm getters. Two of the eight classes (PrivateKeyJwtCustomAudienceTest, PrivateKeyJwtWithX509HeadersTest) reuse KcOidcBrokerPrivateKeyJwtTest's package-private nested PrivateKeyJwtProviderRealmConfig directly, which needs no visibility change since all three classes now live in the same oidc/ package. Two additive extractions on AbstractKcOidcBrokerTest, mirroring the same provider/consumer decomposition the phase-2 branch's KcOidcBrokerConfigSupport already had (independently re-derived here since this branch is based on upstream/main, not on the not-yet-merged keycloak#52372 which added the first one): - createDefaultProviderClient(): same extraction as keycloak#52372, needed here too since half these tests build a customized provider client (different secret/auth method) while reusing the default mapper set. - configureProviderRealm(RealmBuilder, ClientBuilder): new - the realm-level scaffolding (name, event listener, default user) factored out from OidcProviderRealmConfig so a customized client can reuse it instead of duplicating the realm setup. Bugfix in AbstractKcOidcBrokerTest.configureBrokerEndpoints() (pre-existing, not introduced by this batch): the provider-side client redirect-URI rewrite looked up the client by the fixed CLIENT_ID ("brokerapp"), which silently no-ops for any test that creates the provider client under a different clientId - exactly what KcOidcBrokerColonAliasClientSecretBasicAuthTest does to mirror its legacy counterpart's colon-containing client ID. Legacy handled this via a getIDPClientIdInProviderRealm() override precisely because the same lookup-by-fixed-id problem exists there. Fixed by matching on the client's seeded placeholder redirect URI instead of its clientId, which every provider client created via createDefaultProviderClient() carries regardless of what clientId a test assigns it. Caught by actually running this test end-to-end against the new-testsuite framework, not by inspection. Closes keycloak#52243 Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
1a2fc14 to
42d2330
Compare
Migrate KcOidcBrokerJWETest (1 own test), KcOidcBrokerJWEUserInfoJustEncryptedTest, and all 8 ECDH-ES variant tests, all landing in oidc/. Architecture change from the phase-2 branch: the phase-2/interim design used interface traits (JweBrokerConfigSupport, EcdhEsJweBrokerConfigSupport, JweUserInfoBrokerTest) because that's how the whole shared support layer was built at the time. Converted to a 2-layer abstract-class extension instead - AbstractKcOidcJweBrokerTest extends AbstractKcOidcBrokerTest (JWE key/algorithm config + the shared testIdentityClaimsFromUserInfoEndpoint()), and AbstractKcOidcEcdhEsJweBrokerTest extends AbstractKcOidcJweBrokerTest (ECDH-specific key overrides + abstract getCurve()) - rather than keeping them as interfaces mixed in alongside BrokerLoginTest/EcdhEsJweBrokerConfigSupport. Re-examined whether this is genuinely a "multi-axis" case (the documented reason interfaces are reserved over abstract classes elsewhere in this migration): it isn't. Every one of the 10 variants wants the full stack - protocol config, basic login tests, and JWE support - in the same order, with no case needing to skip a layer (unlike e.g. KcOidcBrokerHiddenIdpHintTest in chain expresses this without forcing AbstractBrokerTest's protected fields/methods (oauth, webDriver, logInAsUserInIDP(), etc.) to be widened to public just so interface default methods could call them - interface methods are implicitly public, and a protected inherited method does not satisfy a public abstract interface method, so keeping these as interfaces against the current abstract-class baseline would have forced that wider visibility change. Concrete classes drop straight to their per-variant algorithm/curve overrides (4 one-line methods, or none at all for the RSA base case). Also removes the legacy AbstractKcOidcBrokerJWEEcdhEsTest shared base (all 8 subclasses migrated) and drops all 10 now-migrated class names from the legacy fips-suite list (they are not yet added to the new-testsuite FIPS suites - already tracked separately as deferred pending a test-framework HTTPS-trust fix, per the migration plan's Infrastructure section). Found and fixed another real gap in the merged AbstractBrokerTest (same category as keycloak#52244's disableUpdateProfileOnFirstLogin): enableUnmanagedAttributes() was dropped during the abstract-class rework. Without it, the declarative user profile silently drops attributes outside its managed schema - exactly what this batch's IdP mapper does (maps a custom OIDC claim onto a "user-info" user attribute), so testIdentityClaimsFromUserInfoEndpoint failed identically across all 10 variants until this was restored. Caught by running the tests, not by inspection. Carries forward the visibility widening + configureBrokerEndpoints() and assertUserCreatedInConsumerRealm() fixes from keycloak#52372/keycloak#52376/keycloak#52379 (independently re-derived per batch, this branch is off upstream/main). Closes keycloak#52245 Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
There was a problem hiding this comment.
🟢 Approval recommended
The migrated configurations preserve the legacy scenarios, references are updated, and no unresolved correctness issues were found.
Review details
- Files reviewed: 18/18 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Migrate KcOidcBrokerJWETest (1 own test), KcOidcBrokerJWEUserInfoJustEncryptedTest, and all 8 ECDH-ES variant tests, all landing in oidc/. Architecture change from the phase-2 branch: the phase-2/interim design used interface traits (JweBrokerConfigSupport, EcdhEsJweBrokerConfigSupport, JweUserInfoBrokerTest) because that's how the whole shared support layer was built at the time. Converted to a 2-layer abstract-class extension instead - AbstractKcOidcJweBrokerTest extends AbstractKcOidcBrokerTest (JWE key/algorithm config + the shared testIdentityClaimsFromUserInfoEndpoint()), and AbstractKcOidcEcdhEsJweBrokerTest extends AbstractKcOidcJweBrokerTest (ECDH-specific key overrides + abstract getCurve()) - rather than keeping them as interfaces mixed in alongside BrokerLoginTest/EcdhEsJweBrokerConfigSupport. Re-examined whether this is genuinely a "multi-axis" case (the documented reason interfaces are reserved over abstract classes elsewhere in this migration): it isn't. Every one of the 10 variants wants the full stack - protocol config, basic login tests, and JWE support - in the same order, with no case needing to skip a layer (unlike e.g. KcOidcBrokerHiddenIdpHintTest in chain expresses this without forcing AbstractBrokerTest's protected fields/methods (oauth, webDriver, logInAsUserInIDP(), etc.) to be widened to public just so interface default methods could call them - interface methods are implicitly public, and a protected inherited method does not satisfy a public abstract interface method, so keeping these as interfaces against the current abstract-class baseline would have forced that wider visibility change. Concrete classes drop straight to their per-variant algorithm/curve overrides (4 one-line methods, or none at all for the RSA base case). Also removes the legacy AbstractKcOidcBrokerJWEEcdhEsTest shared base (all 8 subclasses migrated) and drops all 10 now-migrated class names from the legacy fips-suite list (they are not yet added to the new-testsuite FIPS suites - already tracked separately as deferred pending a test-framework HTTPS-trust fix, per the migration plan's Infrastructure section). Found and fixed another real gap in the merged AbstractBrokerTest (same category as #52244's disableUpdateProfileOnFirstLogin): enableUnmanagedAttributes() was dropped during the abstract-class rework. Without it, the declarative user profile silently drops attributes outside its managed schema - exactly what this batch's IdP mapper does (maps a custom OIDC claim onto a "user-info" user attribute), so testIdentityClaimsFromUserInfoEndpoint failed identically across all 10 variants until this was restored. Caught by running the tests, not by inspection. Carries forward the visibility widening + configureBrokerEndpoints() and assertUserCreatedInConsumerRealm() fixes from #52372/#52376/#52379 (independently re-derived per batch, this branch is off upstream/main). Closes #52245 Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
Migrates the OIDC client-authentication and sub-mismatch broker tests to the new JUnit 5 framework, landing in
tests/base/.../broker/oidc/.Two commits, following the project's move-then-adapt pattern (via
tests/migration-util/commit-migration.sh):tests/base/.../tests/broker/oidc/with zero content changes.Config-only variants except
KcOidcBrokerSubMatchIntrospectionTest, which overridestestLogInAsUserInIDPand disablestestLoginWithExistingUser(renamed fromloginWithExistingUserper #51859's 2nd review round - any override of the base method must follow the rename or it silently detaches into a non-@Testmethod).Two of the eight classes (
PrivateKeyJwtCustomAudienceTest,PrivateKeyJwtWithX509HeadersTest) reuseKcOidcBrokerPrivateKeyJwtTest's package-private nestedPrivateKeyJwtProviderRealmConfigdirectly - no visibility change needed since all three now live in the sameoidc/package.Two additive extractions on
AbstractKcOidcBrokerTest, independently re-derived here (this branch is offupstream/main, not the not-yet-merged #52372 which added the first one):createDefaultProviderClient(): same extraction as Migrate OIDC broker config-variant and parameter-forwarding tests #52372 - several of these tests build a customized provider client while reusing the default mapper set.configureProviderRealm(RealmBuilder, ClientBuilder): new - realm-level scaffolding (name, event listener, default user) factored out ofOidcProviderRealmConfigso a customized client can reuse it.Bugfix (pre-existing, not introduced by this batch):
AbstractKcOidcBrokerTest.configureBrokerEndpoints()looked up the provider-side client to rewrite by the fixedCLIENT_ID("brokerapp"), which silently no-ops for any test that creates the provider client under a different clientId - exactly whatKcOidcBrokerColonAliasClientSecretBasicAuthTestdoes to mirror its legacy counterpart's colon-containing client ID (legacy handled this via agetIDPClientIdInProviderRealm()override for the same reason). Fixed by matching on the client's seeded placeholder redirect URI instead of its clientId, which every provider client created viacreateDefaultProviderClient()carries regardless of what clientId a test assigns it. Caught by running the test end-to-end, not by inspection - it would have silently broken any future test needing a non-default provider client ID.The 8 legacy classes carry no
@Testmethods of their own (SubMatchIntrospectionTest's overrides replace, not add to, the two inherited tests), no subclasses, no suite-file references - fully removed rather than left duplicated.Testing
mvn test -Dtest=KcOidcBrokerClientSecretJwtTest,KcOidcBrokerClientSecretJwtCustomSignAlgTest,KcOidcBrokerColonAliasClientSecretBasicAuthTest,KcOidcBrokerPrivateKeyJwtTest,KcOidcBrokerPrivateKeyJwtCustomSignAlgTest,KcOidcBrokerPrivateKeyJwtCustomAudienceTest,KcOidcBrokerPrivateKeyJwtWithX509HeadersTest,KcOidcBrokerSubMatchIntrospectionTest- 15/15 green + 1 intentionally disabledKcOidcBrokerTest,KcOidcBrokerClientSecretBasicAuthTest,KcSamlBrokerTest(phase-1 baseline) - 6/6 green, confirming theconfigureBrokerEndpoints()fix doesn't regress the default pathmvn spotless:checkcleanCloses #5224 8000 3