fix: use OIDC token roles when no claim mapping rules exist
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m29s
CI / docker (push) Successful in 1m15s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 36s

The OIDC callback extracted roles from the token's Custom JWT claim
(e.g. roles: [server:admin]) but never used them. The
applyClaimMappings fallback only assigned defaultRoles (VIEWER).

Now the fallback priority is: claim mapping rules > OIDC token
roles > defaultRoles. This ensures users get their org-mapped
roles (owner → server:admin) without requiring manual claim
mapping rule configuration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-10 12:17:12 +02:00
parent d238d2bd44
commit 0d610be3dc

View File

@@ -156,7 +156,7 @@ public class OidcAuthController {
userId, provider, oidcUser.email(), oidcUser.name(), Instant.now()));
// Apply claim mapping rules to assign managed roles/groups from JWT claims
applyClaimMappings(userId, oidcUser.allClaims(), config.get());
applyClaimMappings(userId, oidcUser.allClaims(), oidcUser.roles(), config.get());
List<String> roles = rbacService.getSystemRoleNames(userId);
@@ -180,7 +180,8 @@ public class OidcAuthController {
}
}
private void applyClaimMappings(String userId, Map<String, Object> claims, OidcConfig oidcConfig) {
private void applyClaimMappings(String userId, Map<String, Object> claims,
List<String> oidcExtractedRoles, OidcConfig oidcConfig) {
List<ClaimMappingRule> rules = claimMappingRepository.findAll();
rbacService.clearManagedAssignments(userId);
@@ -214,15 +215,26 @@ public class OidcAuthController {
}
}
// Fallback: if no mapping rules matched, assign defaultRoles from OIDC config
// Fallback priority: claim mapping rules > OIDC token roles > defaultRoles
if (results.isEmpty()) {
List<String> defaultRoles = oidcConfig.defaultRoles();
if (defaultRoles != null && !defaultRoles.isEmpty()) {
for (String roleName : defaultRoles) {
// Use roles extracted directly from the OIDC token (e.g. Custom JWT 'roles' claim)
if (oidcExtractedRoles != null && !oidcExtractedRoles.isEmpty()) {
for (String roleName : oidcExtractedRoles) {
UUID roleId = SystemRole.BY_NAME.get(SystemRole.normalizeScope(roleName));
if (roleId != null) {
rbacService.assignRoleToUser(userId, roleId);
log.debug("Default role {} assigned to {} (no claim mapping matched)", roleName, userId);
log.info("OIDC role {} assigned to {} (from token claim)", roleName, userId);
}
}
} else {
List<String> defaultRoles = oidcConfig.defaultRoles();
if (defaultRoles != null && !defaultRoles.isEmpty()) {
for (String roleName : defaultRoles) {
UUID roleId = SystemRole.BY_NAME.get(SystemRole.normalizeScope(roleName));
if (roleId != null) {
rbacService.assignRoleToUser(userId, roleId);
log.debug("Default role {} assigned to {} (no claim mapping or OIDC roles)", roleName, userId);
}
}
}
}