feat: support server:-prefixed scopes and case-insensitive role mapping
M2M scope mapping now accepts both 'server:admin' and 'admin' (case- insensitive). OIDC user login role assignment strips the 'server:' prefix before looking up SystemRole, so 'server:viewer' from the id_token maps to VIEWER correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -105,7 +105,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
/**
|
||||
* Maps OAuth2 scopes to server RBAC roles.
|
||||
* Scopes are defined on the Logto API Resource for this server.
|
||||
* Accepts both prefixed ({@code server:admin}) and bare ({@code admin}) scope names,
|
||||
* case-insensitive. Scopes are defined on the Logto API Resource for this server.
|
||||
*/
|
||||
private List<String> extractRolesFromScopes(Jwt jwt) {
|
||||
String scopeStr = jwt.getClaimAsString("scope");
|
||||
@@ -113,12 +114,17 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
return List.of("VIEWER");
|
||||
}
|
||||
List<String> scopes = List.of(scopeStr.split(" "));
|
||||
if (scopes.contains("admin")) return List.of("ADMIN");
|
||||
if (scopes.contains("operator")) return List.of("OPERATOR");
|
||||
if (scopes.contains("viewer")) return List.of("VIEWER");
|
||||
if (hasScope(scopes, "admin")) return List.of("ADMIN");
|
||||
if (hasScope(scopes, "operator")) return List.of("OPERATOR");
|
||||
if (hasScope(scopes, "viewer")) return List.of("VIEWER");
|
||||
return List.of("VIEWER");
|
||||
}
|
||||
|
||||
private boolean hasScope(List<String> scopes, String role) {
|
||||
return scopes.stream().anyMatch(s ->
|
||||
s.equalsIgnoreCase(role) || s.equalsIgnoreCase("server:" + role));
|
||||
}
|
||||
|
||||
private List<GrantedAuthority> toAuthorities(List<String> roles) {
|
||||
return roles.stream()
|
||||
.map(role -> (GrantedAuthority) new SimpleGrantedAuthority("ROLE_" + role))
|
||||
|
||||
@@ -170,7 +170,11 @@ public class OidcAuthController {
|
||||
private void assignRolesForNewUser(String userId, List<String> oidcRoles, OidcConfig config) {
|
||||
List<String> roleNames = !oidcRoles.isEmpty() ? oidcRoles : config.defaultRoles();
|
||||
for (String roleName : roleNames) {
|
||||
UUID roleId = SystemRole.BY_NAME.get(roleName.toUpperCase());
|
||||
String normalized = roleName.toUpperCase();
|
||||
if (normalized.startsWith("SERVER:")) {
|
||||
normalized = normalized.substring("SERVER:".length());
|
||||
}
|
||||
UUID roleId = SystemRole.BY_NAME.get(normalized);
|
||||
if (roleId != null) {
|
||||
rbacService.assignRoleToUser(userId, roleId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user