apereo/cas · warning

Delegated authentication policy for

Error message

Delegated authentication policy for [{}] refuses access to provider [{}]

What it means

BaseDelegatedClientIdentityProviderAuthorizer.handleAuthorizationForService warns and returns false when the registered service's delegated authentication policy (delegatedAuthenticationPolicyEnforcer.execute) rejects the requested identity-provider client name. The provider is thus not allowed for that service even though the service itself is accessible.

Solutions

  1. Add the provider's client name to the service's delegatedAuthenticationPolicy.allowedProviders list in the registered service definition.
  2. Ensure the clientName used matches the allowlist exactly after renaming clients (set explicit client names, update allowlists).
  3. Set allowedProviders to a wildcard/regex if the service should permit all providers.

Example fix

// before: service JSON
"delegatedAuthenticationPolicy": { "allowedProviders": ["SAML2Client"] }
// after
"delegatedAuthenticationPolicy": { "allowedProviders": ["SAML2Client", "my-oidc"] }
Defensive patterns

Strategy: validation

Validate before calling

List<String> allowed = registeredService.getDelegatedAuthenticationPolicy() != null
    ? registeredService.getDelegatedAuthenticationPolicy().getAllowedProviders() : List.of();
if (!allowed.isEmpty() && !allowed.contains(clientName)) { /* provider not authorized for this service */ }

Prevention

When it happens

Trigger: A service definition's delegatedAuthenticationPolicy.allowedProviders does not include the clientName being used (or the policy evaluation otherwise fails), evaluated during isDelegatedClientAuthorizedFor in the delegated authentication flow.

Common situations: Service JSON allowlists specific providers but the user picked/configured a different (or newly-renamed generated) client name; provider renamed or given an explicit name (see error 553) so allowlist entries no longer match; wildcard/no policy set on another service causing policy enforcer misconfiguration.

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.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-pac4j-core/src/main/java/org/apereo/cas/pac4j/client/authz/BaseDelegatedClientIdentityProviderAuthorizer.java:78

            return true;
        }
        val registeredService = servicesManager.findServiceBy(service);
        if (registeredService == null || !registeredService.getAccessStrategy().isServiceAccessAllowed(registeredService, service)) {
            LOGGER.warn("Service access for [{}] is denied", registeredService);
            return false;
        }
        LOGGER.trace("Located registered service definition [{}] matching [{}]", registeredService, service);
        val auditContext = AuditableContext.builder()
            .registeredService(registeredService)
            .service(service)
            .properties(CollectionUtils.wrap(Client.class.getSimpleName(), clientName))
            .build();
        val result = delegatedAuthenticationPolicyEnforcer.execute(auditContext);
        if (!result.isExecutionFailure()) {
            LOGGER.debug("Delegated authentication policy for [{}] allows for using provider [{}]", registeredService, clientName);
            return true;
        }
        LOGGER.warn("Delegated authentication policy for [{}] refuses access to provider [{}]", registeredService.getServiceId(), clientName);
        return false;
    }

    protected boolean isDelegatedClientAuthorizedForTenant(final String clientName, final TenantDefinition tenantDefinition) {
        val allowedProviders = tenantDefinition.getDelegatedAuthenticationPolicy() != null
            ? tenantDefinition.getDelegatedAuthenticationPolicy().getAllowedProviders()
            : List.of();
        val allowedByTenant = StringUtils.isBlank(clientName) || allowedProviders == null
            || allowedProviders.isEmpty() || allowedProviders.contains(clientName);
        LOGGER.debug("Tenant [{}] allows for delegated authentication with provider [{}]: [{}]", tenantDefinition.getId(), clientName,
            BooleanUtils.toStringYesNo(allowedByTenant));
        return allowedByTenant;
    }
}

View on GitHub (pinned to e7288fc434)