apereo/cas · error · AuthenticationException
Authenticated profile does not carry the UMA protection…
Error message
Authenticated profile does not carry the UMA protection scope
What it means
BaseUmaEndpointController.getAuthenticatedProfile reads the authenticated user profile from the Pac4J session store and requires it to hold the requested UMA permission as a role. If the profile lacks that permission, an AuthenticationException is thrown, blocking access to the UMA endpoint. This guards endpoints so only principals with the UMA protection permission proceed.
Solutions
- Ensure the access token used includes the UMA protection scope so the profile gains the required role.
- Check the profile/authorization mapping so the requiredPermission (e.g. uma_protection) is added as a role.
- Re-authenticate to obtain a fresh profile with the correct roles.
- Verify the session store (sessionStore config) used by getUmaConfigurationContext matches the one used at login.
Example fix
// before // profile roles: [] -> AuthenticationException thrown // after // request token with scope=uma_protection; profile roles: [uma_protection]
Defensive patterns
Strategy: try-catch
Validate before calling
UserProfile p = OAuth20Utils.getAuthenticatedUserProfile(context, sessionStore);
if (p == null || !p.getRoles().contains("uma_protection")) {
throw new AuthenticationException("profile lacks UMA permission");
} Try / catch
try { return getAuthenticatedProfile(request, response, permission); } catch (AuthenticationException e) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return null;
} Prevention
- Confirm the authorization generator maps the UMA scope to a profile role
- Use the same sessionStore at login and endpoint access time
- Test the full token-to-profile flow, not just token issuance
When it happens
Trigger: Calling a UMA controller endpoint (resource-set registration, permission, etc.) with a session whose profile does not include the requiredPermission role, e.g. the user authenticated but was never granted the UMA protection scope/role.
Common situations: Direct browser access to UMA endpoints without the token-based profile carrying the role; session store losing profile attributes; misconfigured authorization generator not mapping the uma_protection scope to a role.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Denied
- Cannot authorize principal
- Unauthorized account removal attempt
- Unknown authorization header type
- Authentication request does contain a client id
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/c646f93ea9e3487b.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-oauth-uma-core/src/main/java/org/apereo/cas/uma/web/controllers/BaseUmaEndpointController.java:50
*/
@Getter
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class BaseUmaEndpointController extends AbstractController {
/**
* Json object mapper instance.
*/
protected static final ObjectMapper MAPPER = JacksonObjectMapperFactory.builder()
.defaultTypingEnabled(false).build().toObjectMapper();
private final UmaConfigurationContext umaConfigurationContext;
protected UserProfile getAuthenticatedProfile(final HttpServletRequest request,
final HttpServletResponse response,
final String requiredPermission) {
val context = new JEEContext(request, response);
val profile = OAuth20Utils.getAuthenticatedUserProfile(context, getUmaConfigurationContext().getSessionStore());
if (!profile.getRoles().contains(requiredPermission)) {
throw new AuthenticationException("Authenticated profile does not carry the UMA protection scope");
}
return profile;
}
protected MultiValueMap<String, Object> buildResponseEntityErrorModel(final InvalidResourceSetException e) {
return buildResponseEntityErrorModel(e.getStatus(), e.getMessage());
}
protected MultiValueMap<String, Object> buildResponseEntityErrorModel(final HttpStatus code, final String message) {
return CollectionUtils.asMultiValueMap("code",
code.value(),
"message", message);
}
protected OAuth20AccessToken resolveAccessToken(final Ticket token) {
return (OAuth20AccessToken) (token.isStateless() ? umaConfigurationContext.getTicketRegistry().getTicket(token.getId()) : token);
}
View on GitHub (pinned to e7288fc434)