feat: generic OIDC role extraction from access token
The OIDC login flow now reads roles from the access_token (JWT) in addition to the id_token. This fixes role extraction with providers like Logto that put scopes/roles in access tokens rather than id_tokens. - Add audience and additionalScopes to OidcConfig for RFC 8707 resource indicator support and configurable extra scopes - OidcTokenExchanger decodes access_token with at+jwt-compatible processor, falls back to id_token if access_token is opaque or has no roles - syncOidcRoles preserves existing local roles when OIDC returns none - SPA includes resource and additionalScopes in authorization requests - Admin UI exposes new config fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,5 +14,7 @@ public record OidcAdminConfigRequest(
|
||||
List<String> defaultRoles,
|
||||
boolean autoSignup,
|
||||
String displayNameClaim,
|
||||
String userIdClaim
|
||||
String userIdClaim,
|
||||
String audience,
|
||||
List<String> additionalScopes
|
||||
) {}
|
||||
|
||||
@@ -17,10 +17,12 @@ public record OidcAdminConfigResponse(
|
||||
List<String> defaultRoles,
|
||||
boolean autoSignup,
|
||||
String displayNameClaim,
|
||||
String userIdClaim
|
||||
String userIdClaim,
|
||||
String audience,
|
||||
List<String> additionalScopes
|
||||
) {
|
||||
public static OidcAdminConfigResponse unconfigured() {
|
||||
return new OidcAdminConfigResponse(false, false, null, null, false, null, null, false, null, null);
|
||||
return new OidcAdminConfigResponse(false, false, null, null, false, null, null, false, null, null, null, null);
|
||||
}
|
||||
|
||||
public static OidcAdminConfigResponse from(OidcConfig config) {
|
||||
@@ -28,7 +30,7 @@ public record OidcAdminConfigResponse(
|
||||
true, config.enabled(), config.issuerUri(), config.clientId(),
|
||||
!config.clientSecret().isBlank(), config.rolesClaim(),
|
||||
config.defaultRoles(), config.autoSignup(), config.displayNameClaim(),
|
||||
config.userIdClaim()
|
||||
config.userIdClaim(), config.audience(), config.additionalScopes()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,9 @@ public record OidcPublicConfigResponse(
|
||||
@NotNull String clientId,
|
||||
@NotNull String authorizationEndpoint,
|
||||
@Schema(description = "Present if the provider supports RP-initiated logout")
|
||||
String endSessionEndpoint
|
||||
String endSessionEndpoint,
|
||||
@Schema(description = "RFC 8707 resource indicator for the authorization request")
|
||||
String resource,
|
||||
@Schema(description = "Additional scopes to request beyond openid email profile")
|
||||
java.util.List<String> additionalScopes
|
||||
) {}
|
||||
|
||||
Reference in New Issue
Block a user