Add option to include empty organization claim - #50745
Conversation
Closes #50410 Co-Authored-By: openai-codex <noreply@openai.com> Signed-off-by: Develop-KIM <kimdonghwan913@gmail.com>
b7056e4 to
f8fd7f3
Compare
There was a problem hiding this comment.
Pull request overview
This PR resolves issue #50410 by adding an opt-in includeEmptyClaim setting to the Organization Membership OIDC protocol mapper. Previously, when a user belonged to zero organizations, the organization claim was entirely omitted from tokens, making an authoritative "member of nothing" indistinguishable from a missing/dropped claim. With the new flag (default false, preserving backward compatibility), the mapper can emit a deterministic empty value ([] for multivalued, {} for JSON) across access token, ID token, userinfo, and introspection output.
The implementation works around OIDCAttributeMapperHelper.mapClaim (which drops empty collections via mapAttributeValue) by detecting the empty claim in setClaim and writing it directly with JsonUtils.mapClaim. The default path (flag off) still returns null, so existing behavior is unchanged.
Changes:
- Added
INCLUDE_EMPTY_CLAIMconfig property andresolveEmptyValue/isEmptyClaim/mapEmptyClaimhelpers toOrganizationMembershipMapper. - Added admin UI label/help text for the new option.
- Added integration tests covering the empty-claim output for list and JSON claim types across access/ID/userinfo tokens.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
services/.../oidc/OrganizationMembershipMapper.java |
Adds the includeEmptyClaim option and logic to emit an empty claim for org-less users. |
js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties |
Adds the admin UI label and help text for the new mapper option. |
testsuite/.../organization/mapper/OrganizationOIDCProtocolMapperTest.java |
Adds tests verifying empty-claim output for list/JSON types and a helper to promote the org scope to a default scope. |
| if (OIDCAttributeMapperHelper.isMultivalued(model)) { | ||
| return List.of(); | ||
| } | ||
|
|
||
| return null; |
Closes #50410 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Develop-KIM <kimdonghwan913@gmail.com>
Closes #50410
Summary
includeEmptyClaimsetting to the organization membership mapper.Verification
./mvnw -pl services -am -DskipTests compile./mvnw -pl testsuite/integration-arquillian/tests/base -am -DskipTests install./mvnw -pl testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.organization.mapper.OrganizationOIDCProtocolMapperTest#testEmptyOrganizationClaimMappedWhenConfigured test./mvnw -pl testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.organization.mapper.OrganizationOIDCProtocolMapperTest#testEmptyOrganizationClaimMappedAsJsonWhenConfigured clean test./mvnw -pl services,testsuite/integration-arquillian/tests/base spotless:checkgit diff --checkDisclosure
This contribution was prepared with AI assistance and reviewed before submission.