{"record":{"id":"c646f93ea9e3487b","repo":"apereo/cas","slug":"authenticated-profile-does-not-carry-the-uma-prote","errorCode":null,"errorMessage":"Authenticated profile does not carry the UMA protection scope","messagePattern":"Authenticated profile does not carry the UMA protection scope","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-oauth-uma-core/src/main/java/org/apereo/cas/uma/web/controllers/BaseUmaEndpointController.java","lineNumber":50,"sourceCode":" */\n@Getter\n@RequiredArgsConstructor(access = AccessLevel.PROTECTED)\npublic abstract class BaseUmaEndpointController extends AbstractController {\n    /**\n     * Json object mapper instance.\n     */\n    protected static final ObjectMapper MAPPER = JacksonObjectMapperFactory.builder()\n        .defaultTypingEnabled(false).build().toObjectMapper();\n\n    private final UmaConfigurationContext umaConfigurationContext;\n\n    protected UserProfile getAuthenticatedProfile(final HttpServletRequest request,\n                                                  final HttpServletResponse response,\n                                                  final String requiredPermission) {\n        val context = new JEEContext(request, response);\n        val profile = OAuth20Utils.getAuthenticatedUserProfile(context, getUmaConfigurationContext().getSessionStore());\n        if (!profile.getRoles().contains(requiredPermission)) {\n            throw new AuthenticationException(\"Authenticated profile does not carry the UMA protection scope\");\n        }\n        return profile;\n    }\n\n    protected MultiValueMap<String, Object> buildResponseEntityErrorModel(final InvalidResourceSetException e) {\n        return buildResponseEntityErrorModel(e.getStatus(), e.getMessage());\n    }\n\n    protected MultiValueMap<String, Object> buildResponseEntityErrorModel(final HttpStatus code, final String message) {\n        return CollectionUtils.asMultiValueMap(\"code\",\n            code.value(),\n            \"message\", message);\n    }\n\n    protected OAuth20AccessToken resolveAccessToken(final Ticket token) {\n        return (OAuth20AccessToken) (token.isStateless() ? umaConfigurationContext.getTicketRegistry().getTicket(token.getId()) : token);\n    }\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-oauth-uma-core/src/main/java/org/apereo/cas/uma/web/controllers/BaseUmaEndpointController.java#L32-L68","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n// profile roles: [] -> AuthenticationException thrown\n// after\n// request token with scope=uma_protection; profile roles: [uma_protection]","handlingStrategy":"try-catch","validationCode":"UserProfile p = OAuth20Utils.getAuthenticatedUserProfile(context, sessionStore);\nif (p == null || !p.getRoles().contains(\"uma_protection\")) {\n    throw new AuthenticationException(\"profile lacks UMA permission\");\n}","typeGuard":null,"tryCatchPattern":"try { return getAuthenticatedProfile(request, response, permission); } catch (AuthenticationException e) {\n    response.sendError(HttpServletResponse.SC_FORBIDDEN);\n    return null;\n}","preventionTips":["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"],"tags":["uma","authorization","profile","missing-role"],"backgroundTag":"permission-denied","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}