apereo/cas · error · UnauthorizedServiceException

Realm [ ] is not authorized for the identity provider realm…

Error message

Realm [{}] is not authorized for the identity provider realm [{}]

What it means

The realm of the registered WS-Federation service does not match the identity provider's own configured realm (cas.authn.wsfed-idp.idp.realm), so the federation request is rejected with UnauthorizedServiceException.denied(). This is an IdP-wide configuration mismatch, distinct from the per-request wtrealm check.

Solutions

  1. Align cas.authn.wsfed-idp.idp.realm with the realm on all WS-Federation registered services
  2. Update the affected registered service definitions' realm to the IdP realm
  3. Re-check config after environment promotion so IdP and services use matching realms

Example fix

// before
cas.authn.wsfed-idp.idp.realm=https://old-idp.example.com
// after
cas.authn.wsfed-idp.idp.realm=https://idp.example.com
Defensive patterns

Strategy: validation

Validate before calling

if (!idpRealm.equalsIgnoreCase(service.getRealm())) throw new IllegalStateException("Service realm must equal IdP realm: " + idpRealm);

Prevention

When it happens

Trigger: findAndValidateFederationRequestForRegisteredService(): after the wtrealm check passes, Strings.CI.equals(idp.getRealm(), svc.getRealm()) is false and UnauthorizedServiceException is thrown.

Common situations: CAS IdP realm property changed or mis-typed during migration; services were created against a different IdP realm (e.g. staging vs production host); copy-pasted service definitions from another CAS environment.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-ws-idp/src/main/java/org/apereo/cas/ws/idp/web/BaseWSFederationRequestController.java:135

            val createdDate = idpToken.getCreated();
            if (createdDate != null) {
                val expiryDate = new Date(createdDate.toEpochMilli() + ttlMs);
                return expiryDate.before(new Date());
            }
        }
        return false;
    }

    protected WSFederationRegisteredService findAndValidateFederationRequestForRegisteredService(final Service targetService,
                                                                                                 final WSFederationRequest fedRequest) {
        val svc = getWsFederationRegisteredService(targetService);
        if (StringUtils.isBlank(fedRequest.wtrealm()) || !Strings.CI.equals(fedRequest.wtrealm(), svc.getRealm())) {
            LOGGER.warn("Realm [{}] is not authorized for matching service [{}]", fedRequest.wtrealm(), svc);
            throw UnauthorizedServiceException.denied("Rejected: %s".formatted(svc.getRealm()));
        }
        val idp = configContext.getCasProperties().getAuthn().getWsfedIdp().getIdp();
        if (!Strings.CI.equals(idp.getRealm(), svc.getRealm())) {
            LOGGER.warn("Realm [{}] is not authorized for the identity provider realm [{}]", fedRequest.wtrealm(), idp.getRealm());
            throw UnauthorizedServiceException.denied("Rejected: %s".formatted(svc.getRealm()));
        }

        return svc;
    }

    protected WSFederationRegisteredService getWsFederationRegisteredService(final Service targetService) {
        val svc = configContext.getServicesManager().findServiceBy(targetService, WSFederationRegisteredService.class);
        RegisteredServiceAccessStrategyUtils.ensureServiceAccessIsAllowed(targetService, svc);
        return svc;
    }

    /**
     * Handle unauthorized service exception.
     *
     * @param req the req
     * @param ex  the ex
     * @return the model and view

View on GitHub (pinned to e7288fc434)