Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
A Spring Boot API can accept a Keycloak access token and still deny a user because token authentication and role authorization are separate steps. Keycloak’s default role claims are nested under realm_access.roles or resource_access.<client>.roles; Spring Security’s JWT resource-server defaults map scopes to SCOPE_ authorities and do not automatically convert those nested claims into role authorities. First inspect the access token sent with the failing request, then fix Keycloak if the role is absent or Spring’s authority conversion and authorization rule if it is present.
Why a valid Keycloak token can still fail a Spring role check
Authentication establishes that the request presented a token Spring accepts. Authorization decides whether the authenticated principal has an authority required by a rule. A JWT can pass signature and standard-claim validation while Spring has no matching GrantedAuthority for a Keycloak role. Spring’s resource-server JWT support is scope-oriented by default: scopes become authorities such as SCOPE_read, not automatically ROLE_ADMIN from a nested Keycloak claim. See Spring Security’s JWT resource-server documentation.
That distinction often explains a 403 or a failed method or request authorization check when the token itself authenticated. If authentication fails instead, investigate token validation separately.
Find where Keycloak put the role
Decode the bearer access token that actually reaches the API. Do not substitute an ID token or a different token obtained during testing. Keycloak’s default role claim locations are:
#1 Best Overall
realm_access.rolesfor realm roles.resource_access.<client>.rolesfor roles associated with a client. The client name in the claim path must be the one whose roles the API intends to use.
For example, a client role might appear as resource_access.orders-api.roles. The exact representation can differ if protocol mappers have been changed. Keycloak documents its role claims and protocol mappers in the Keycloak Server Administration Guide 26.7.0.
Check the token’s exact claim spelling, nesting, and capitalization. If the expected role is missing, changing a Spring converter cannot create it; fix token issuance in Keycloak. If it is present, focus on Spring’s extraction and the authority string expected by the access rule.
If the role is missing, check Keycloak’s effective role mappings
A role assigned to a user is not necessarily included in every client’s token. Role claims depend on the user’s effective roles and the role-scope mappings available to the client, as well as the protocol mappers that represent them in token claims. Keycloak describes role-scope mappings and their effect on tokens in its Server Administration Guide 26.8.0.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →- Check the user’s effective roles. Review direct assignments, group-derived roles, and composite roles. If the token is for a service account, check that account’s role assignments too.
- Check the client’s role-scope mappings. Confirm the client can expose the role in question, rather than assuming that an assignment alone makes it appear.
- Inspect the roles client scope and protocol mappers. Verify that the relevant mapper is enabled and places the role in the claim path your API expects.
- Use client-scope evaluation where available. Keycloak’s evaluation view can show the scopes, mappers, and role-scope mappings effective for a particular user and client, and preview the resulting token.
Avoid enabling broad role exposure just to make one check pass. Keycloak’s 26.8 guide describes role-scope mappings as a way to limit which roles are declared in a token; it also says the Full Scope Allowed switch is deprecated and is to be removed in a future release. Console labels and behavior can vary with the Keycloak version and deployment.
Rank #3
If the role is present, convert it into the authority Spring checks
Spring needs an authority whose name matches the application’s authorization rule. For a flat custom claim, JwtGrantedAuthoritiesConverter can be configured with an authorities claim name and a prefix. Keycloak’s usual role claims are nested objects, so a converter must traverse the appropriate path, such as realm_access.roles or the chosen entry under resource_access. Spring documents this extension point and its claim and prefix options in the JwtGrantedAuthoritiesConverter API reference.
For example, this illustrates extracting realm roles and adding a ROLE_ prefix:
Rank #4
- Made in USA - Proudly produced in Ohio by a Veteran-owned business
- Comprehensive Coverage: This BookFactory log book includes essential fields such as post/shift, time of change, date, weather conditions, and a designated space for detailed notes. This ensures that all relevant information is captured and easily accessible.
- Sturdy Cover: The trans-lux cover protects the log book from wear and tear, ensuring its longevity and maintaining the integrity of your recorded data.
- Essential Security Tool: This log book is an indispensable tool for any organization that values security and accountability. It helps to prevent misunderstandings, improve communication, and ensure a smooth transition between shifts.
- Wire-O with Trans-lux cover, 100 Pages, Dimensions 8.5" x 11" - (Security-Pass-Down) Reorder SKU: LOG-100-7CW-PP(Security-Pass-Down)
Map<String, Object> realmAccess = jwt.getClaim("realm_access");
if (realmAccess == null) return List.of();
Object rawRoles = realmAccess.get("roles");
if (!(rawRoles instanceof Collection<?> roles)) return List.of();
return roles.stream()
.map(Object::toString)
.map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.toList();
This is an extraction illustration, not a complete security configuration. Adapt it to the project’s Java and Spring versions, handle claim types and nulls appropriately, and decide deliberately whether to include realm roles, client roles, or both. Do not turn arbitrary token claims into authorization authorities. If the application should retain both scope authorities and role authorities, Spring provides DelegatingJwtGrantedAuthoritiesConverter to aggregate converters; see its API reference.
Match the authority name to the authorization rule
The converter’s output and the access rule must agree exactly. A typical role-style rule such as hasRole("admin") checks for ROLE_admin by convention. hasAuthority checks the literal authority string supplied. Thus, a token role named admin does not match SCOPE_admin or ROLE_ADMIN unless your conversion and rule establish that same string. Verify the exact matcher behavior for the Spring Security version and configuration in use.
| Situation | What to change |
|---|---|
| Expected role is absent from the access token | Check the user’s effective roles, client role-scope mappings, and protocol mappers in Keycloak. |
| Role exists in a nested token claim, but no corresponding Spring authority appears | Configure a converter to extract the intended realm or client role claim. |
| Spring creates an authority, but authorization still denies access | Align its exact name and prefix with the rule, such as ROLE_admin for a role-style check. |
| Authentication fails before authorization | Diagnose issuer, signature/JWK configuration, expiry, not-before, and resource-server setup; role conversion does not fix an invalid token. |
Separate token validation failures from role failures
When Spring rejects authentication rather than merely denying access, inspect issuer and signature/JWK configuration, token expiry and not-before values, and the resource-server setup. Spring’s issuer-based resource-server configuration validates the JWT signature and standard claims including exp, nbf, and iss, as described in its JWT documentation. A role converter runs after token authentication; it cannot make an invalid or expired token valid.
Keycloak’s claim paths above are defaults documented for version 26.7.0, and role-scope guidance cited here is from version 26.8.0. The Spring references cover 6.5 and 7.1 documentation. Since the application’s versions and servlet or reactive setup are unspecified, check the actual token, mapper configuration, and version-specific API documentation before adapting converter code.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

