{"record":{"id":"9ef3b405b78b26ad","repo":"apereo/cas","slug":"unauthorized-service-proxy","errorCode":"UNAUTHORIZED_SERVICE_PROXY","errorMessage":"Proxying is not allowed for registered service ","messagePattern":"Proxying is not allowed for registered service ","errorType":"exception","errorClass":"UnauthorizedProxyingException","httpStatus":null,"severity":"error","filePath":"core/cas-server-core/src/main/java/org/apereo/cas/AbstractCentralAuthenticationService.java","lineNumber":82,"sourceCode":"        } catch (final Throwable e) {\n            LoggingUtils.error(LOGGER, e);\n        }\n        throw new UnsatisfiedAuthenticationPolicyException(policy);\n    }\n\n    protected void evaluateProxiedServiceIfNeeded(@Nullable final Service service,\n                                                  final TicketGrantingTicket ticketGrantingTicket,\n                                                  @Nullable final RegisteredService registeredService) {\n        val proxiedBy = ticketGrantingTicket.getProxiedBy();\n        if (proxiedBy != null) {\n            LOGGER.debug(\"Ticket-granting ticket is proxied by [{}]. Locating proxy service in registry...\", proxiedBy.getId());\n            val proxyingService = configurationContext.getServicesManager().findServiceBy(proxiedBy, CasModelRegisteredService.class);\n            if (proxyingService != null) {\n                LOGGER.debug(\"Located proxying service [{}] in the service registry\", proxyingService);\n                if (!proxyingService.getProxyPolicy().isAllowedToProxy()) {\n                    LOGGER.warn(\"Proxying service [{}] is not authorized to fulfill the proxy attempt made by [{}]\",\n                        proxyingService.getId(), Objects.requireNonNull(service).getId());\n                    throw new UnauthorizedProxyingException(UnauthorizedProxyingException.MESSAGE + Objects.requireNonNull(registeredService).getId());\n                }\n            } else {\n                LOGGER.warn(\"Proxy attempt by service [{}] (registered service [{}]) is not allowed.\",\n                    Objects.requireNonNull(service).getId(), Objects.requireNonNull(registeredService).getId());\n                throw new UnauthorizedProxyingException(UnauthorizedProxyingException.MESSAGE + registeredService.getId());\n            }\n        } else {\n            LOGGER.trace(\"Ticket-granting ticket is not proxied by another service\");\n        }\n    }\n\n    protected @Nullable Service resolveServiceFromAuthenticationRequest(final Service service) throws Throwable {\n        return configurationContext.getAuthenticationServiceSelectionPlan().resolveService(service, Service.class);\n    }\n\n    protected boolean isTicketAuthenticityVerified(final String ticketId) {\n        try {\n            if (configurationContext.getCipherExecutor() != null) {","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core/src/main/java/org/apereo/cas/AbstractCentralAuthenticationService.java#L64-L100","documentation":"When a TicketGrantingTicket was obtained by another service (proxiedBy), AbstractCentralAuthenticationService.evaluateProxiedServiceIfNeeded checks that proxying service's ProxyPolicy. If the policy disallows proxying, it throws UnauthorizedProxyingException (code UNAUTHORIZED_SERVICE_PROXY) naming the registered service id.","triggerScenarios":"Requesting a proxy ticket or ST with a PGT where the pgtUrl's service (proxiedBy) is registered but its registeredService.getProxyPolicy().isAllowedToProxy() is false (e.g. default RefusePermissionToProxyPolicy).","commonSituations":"Service registered without proxy-granting policy enabled (org.apereo.cas.services.RegexMatchingRegisteredServiceProxyPolicy not set); service not registered at all; CAS 5+ stricter proxy policy enforcement breaking legacy PGT clients.","solutions":["Update the registered service to allow proxying: set a proxy policy, e.g. new RegexMatchingRegisteredServiceProxyPolicy(\"^https://your-service/.*\")","Ensure the proxying (callback) URL itself is registered in the service registry","If proxying is not needed, stop requesting PGT/PTs and use plain service tickets","Set service proxyPolicy explicitly in the JSON/YAML service definition instead of relying on defaults"],"exampleFix":"// before (default: refuse)\n\"proxyPolicy\": null\n// after\n{\n  \"@class\": \"org.apereo.cas.services.RegexMatchingRegisteredServiceProxyPolicy\",\n  \"pattern\": \"^https://proxy-consumer\\.example\\.org/.*\"\n}","handlingStrategy":"validation","validationCode":"RegisteredService svc = servicesManager.findServiceBy(proxiedBy);\nboolean mayProxy = svc != null && svc.getProxyPolicy() != null && svc.getProxyPolicy().isAllowedToProxy();\nif (!mayProxy) throw new IllegalStateException(\"Enable proxy policy for \" + proxiedBy);","typeGuard":null,"tryCatchPattern":"try {\n    centralAuthenticationService.grantProxyTicket(...);\n} catch (UnauthorizedProxyingException e) {\n    logger.error(\"Proxying refused for service {}: {}\", serviceId, e.getMessage());\n}","preventionTips":["Set an allowing proxy policy on services that need PGTs","Register the proxy callback (proxiedBy) URL in the service registry","Audit service definitions after CAS upgrades — proxy defaults are strict"],"tags":["proxy-ticket","registered-service","unauthorized"],"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"}