apereo/cas · error

Service [ ] is not authorized

Error message

Service [{}] is not authorized

What it means

RegisteredServiceResponseHeadersEnforcementFilter.prepareFilterBeforeExecution logs 'Service [x] is not authorized' when the registered service access strategy enforcer reports an execution failure. The filter then responds HTTP 403 FORBIDDEN, stores the access exception as a request attribute, and skips adding the service's enforced response headers.

Solutions

  1. Inspect the request attribute ERROR_EXCEPTION / logs for the underlying access strategy exception to learn the denial reason.
  2. Fix the registered service definition: enable it, correct the service URL/pattern, or update the access strategy (authorized users, attributes, time window).
  3. Verify attribute release/attribute repository sources so required attributes are available at enforcement time.
  4. If the service should not be governed by this filter, adjust the filter/exclusion configuration rather than the service policy.
  5. Confirm the CAS node can reach backing stores (LDAP/Groovy policy) — unreachable sources can cause execution failure.

Example fix

// before: service JSON denies access
"accessStrategy": { "@class": "DefaultRegisteredServiceAccessStrategy", "enabled": false }
// after
"accessStrategy": { "@class": "DefaultRegisteredServiceAccessStrategy", "enabled": true, "ssoEnabled": true }
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check access before relying on response headers:
var audit = RegisteredServiceAccessStrategyAudit.builder()
    .registeredService(registeredService).service(service).build();
if (accessEnforcer.execute(audit).isExecutionFailure()) {
    LOGGER.warn("Service {} will be denied; fix access strategy", service.getId());
}

Type guard

boolean isServiceAccessible(RegisteredService svc, Principal p) {
    return svc.getAccessStrategy().isServiceAccessAllowed(svc, p);
}

Prevention

When it happens

Trigger: An incoming request matches a registered service, but RegisteredServiceAccessStrategyEnforcer.execute denies access — e.g. service disabled/unauthorized, access strategy case-sensitive name mismatch, unauthorized email/domain, missing required attributes, or time/day restrictions in the service definition.

Common situations: Service registry entry disabled or expired; attribute-based release policy denies the current principal; the service URL pattern matches but access strategy rules (delegated policy, LDAP-backed policy) fail; environment where the enforcer bean throws (upstream exceptions surfaced via accessResult.getException()).

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/689d115565fb322c. Report an issue: GitHub.

Appendix: source

Thrown at core/cas-server-core-web-api/src/main/java/org/apereo/cas/services/web/support/RegisteredServiceResponseHeadersEnforcementFilter.java:95

            return Optional.empty();
        }
        
        val service = argumentExtractor.getObject().extractService(httpServletRequest);
        if (service != null) {
            LOGGER.trace("Attempting to resolve service for [{}]", service);
            val resolved = authenticationRequestServiceSelectionStrategies.getObject().resolveService(service);
            val servicesManager = servicesManagerProvider.getObject();
            val registeredService = NumberUtils.isCreatable(resolved.getId())
                ? servicesManager.findServiceBy(Long.parseLong(resolved.getId()))
                : servicesManager.findServiceBy(resolved);
            val audit = AuditableContext
                .builder()
                .registeredService(registeredService)
                .service(service)
                .build();
            val accessResult = registeredServiceAccessStrategyEnforcer.getObject().execute(audit);
            if (accessResult.isExecutionFailure()) {
                LOGGER.warn("Service [{}] is not authorized", resolved);
                httpServletResponse.setStatus(HttpStatus.FORBIDDEN.value());
                httpServletRequest.setAttribute(RequestDispatcher.ERROR_EXCEPTION, accessResult.getException().orElse(null));
                return Optional.empty();
            }
            return Optional.of(registeredService);
        }
        return Optional.empty();
    }
    @Override
    protected void decideInsertContentSecurityPolicyHeader(final HttpServletResponse httpServletResponse,
                                                           final HttpServletRequest httpServletRequest,
                                                           final Optional<RegisteredService> result) {

        val shouldInject = shouldHttpHeaderBeInjectedIntoResponse(result,
            RegisteredServiceProperties.HTTP_HEADER_ENABLE_CONTENT_SECURITY_POLICY);

        if (shouldInject.isPresent()) {
            if (shouldInject.get()) {

View on GitHub (pinned to e7288fc434)