apereo/cas · error · AuthenticationException
Unable to authenticate request to register service
Error message
Unable to authenticate request to register service ${service.name} What it means
RegisteredServiceResource.createService throws AuthenticationException when authenticateRequest(request) returns null, i.e. the management REST call to register a service carried no recognizable authentication (typically missing/invalid HTTP Basic credentials). The endpoint refuses to save the service without an authenticated, authorized caller.
Solutions
- Send HTTP Basic Authorization credentials with the request: curl -u admin:password -X POST .../v1/services.
- Verify the credentials are valid against the configured REST/basic-auth authentication source.
- Ensure no proxy or client library strips or rewrites the Authorization header.
- Check the RegisteredServiceResource authentication configuration (service factory, authenticationSystemSupport beans) is present in the deployed overlay.
Example fix
// before
curl -X POST 'https://cas/v1/services' -H 'Content-Type: application/json' -d '{...}'
// after
curl -u casadmin:secret -X POST 'https://cas/v1/services' -H 'Content-Type: application/json' -d '{...}' Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: ensure an Authorization header is present before calling the endpoint
if (authHeader == null || !authHeader.startsWith("Basic ")) {
throw new IllegalArgumentException("Service registration requires HTTP Basic Authorization header");
} Try / catch
try { registerService(service, adminUser, adminPass); }
catch (AuthenticationException e) {
logger.error("REST management auth failed; check credentials/config: " + e.getMessage());
throw new IllegalStateException("Service registration requires valid admin credentials", e);
} Prevention
- Always send -u user:password (Basic auth) for /v1/services management calls.
- Verify the Authorization header survives proxies and client libraries.
- Keep management credentials in sync with the configured authentication source.
- Test the credential against the auth source independently before automation runs.
When it happens
Trigger: POST to /cas/v1/services without an Authorization header; Basic auth header malformed or Base64 mis-encoded; credentials rejected so the underlying authentication result is null; the endpoint's basic-auth/ECP credential extraction path silently fails.
Common situations: Admin automation scripts omit the -u user:password option; wrong REST admin username/password after a config change; reverse proxy strips the Authorization header; CAS REST services authentication configuration (cas.authn.rest or management security settings) points at an unavailable auth source.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- No credentials are provided or extracted to authenticate…
- Unable to accept response status
- No credentials can be extracted to authenticate the REST…
- Unable to extract credentials for multifactor authentication
- Radius authentication failed for user
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/3cbfbd7624fa5223.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-rest-services/src/main/java/org/apereo/cas/support/rest/RegisteredServiceResource.java:86
* @return {@link ResponseEntity} representing RESTful response
*/
@PostMapping(value = "/v1/services", consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Create registered service",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
required = true,
description = "Registered service JSON payload",
content = @Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(implementation = RegisteredService.class)
)
))
public ResponseEntity<String> createService(@RequestBody final RegisteredService service,
final HttpServletRequest request,
final HttpServletResponse response) {
try {
val auth = authenticateRequest(request);
if (auth == null) {
throw new AuthenticationException("Unable to authenticate request to register service " + service.getName());
}
if (isAuthenticatedPrincipalAuthorized(auth)) {
this.servicesManager.save(service);
return new ResponseEntity<>(HttpStatus.OK);
}
return new ResponseEntity<>("Request is not authorized", HttpStatus.FORBIDDEN);
} catch (final AuthenticationException e) {
return new ResponseEntity<>(StringEscapeUtils.escapeHtml4(e.getMessage()), HttpStatus.UNAUTHORIZED);
} catch (final Exception e) {
LoggingUtils.error(LOGGER, e);
return new ResponseEntity<>(StringEscapeUtils.escapeHtml4(e.getMessage()), HttpStatus.BAD_REQUEST);
}
}
private boolean isAuthenticatedPrincipalAuthorized(final Authentication auth) {
val attributes = auth.getPrincipal().getAttributes();
LOGGER.debug("Evaluating principal attributes [{}]", attributes.keySet());
if (StringUtils.isBlank(this.attributeName) || StringUtils.isBlank(this.attributeValue)) {View on GitHub (pinned to e7288fc434)