apereo/cas · warning

Provided authentication result is undefined to evaluate for…

Error message

Provided authentication result is undefined to evaluate for mixed principals

What it means

evaluatePossibilityOfMixedPrincipals in DefaultCentralAuthenticationService warns and returns null when a null AuthenticationResult is supplied while comparing the TGT's principal with a new authentication result. It guards the mixed-principal detection during TGT re-establishment; null means the check could not be performed, so the caller treats it as 'no mixed principal detected'.

Solutions

  1. Ensure an AuthenticationResult is built and passed whenever a TGT is presented for re-evaluation
  2. Check the authentication handler chain: a failed/aborted authentication produces a null result — fix the underlying authentication failure first
  3. If the null result is intentional (pure SSO re-use), treat the warn as benign and confirm mixed-principal policy tolerates it
  4. Review custom CentralAuthenticationService call sites for paths that skip authentication result creation

Example fix

// before
acs.grantTicketGrantingTicket(tgtId, null);
// after
val result = authenticationResultBuilder.build(fixedCredentials, service);
acs.grantTicketGrantingTicket(tgtId, result);
Defensive patterns

Strategy: validation

Validate before calling

if (authenticationResult == null) {
    throw new IllegalArgumentException("AuthenticationResult required when a TGT is presented");
}

Type guard

boolean canEvaluate = context != null && context.getAuthentication() != null && ticketGrantingTicket.getAuthentication() != null;

Prevention

When it happens

Trigger: Calling grantTicketGrantingTicket/evaluatePossibilityOfMixedPrincipals (via CentralAuthenticationService flows) with a null AuthenticationResult context alongside an existing TicketGrantingTicket — e.g. an SSO session refresh where no fresh authentication result was built.

Common situations: Custom authentication flows or protocol handlers (SAML/OIDC delegating flows) that re-use a TGT without producing a new AuthenticationResult; misconfigured service ticket grant flows that pass a null result after a failed authentication attempt.

Understand the failure class

Related errors


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

Appendix: source

Thrown at core/cas-server-core/src/main/java/org/apereo/cas/DefaultCentralAuthenticationService.java:409

            .build();
        enforceRegisteredServiceAccess(audit);
    }

    protected @Nullable Principal rebuildStatelessTicketPrincipal(final ServiceTicket serviceTicket) throws Throwable {
        val authentication = serviceTicket.getAuthentication();
        return configurationContext.getPrincipalResolver()
            .resolve(new BasicIdentifiableCredential(
                    Objects.requireNonNull(authentication).getPrincipal().getId()),
                Optional.of(authentication.getPrincipal()), Optional.empty(),
                Optional.of(serviceTicket.getService()));
    }

    private static @Nullable Authentication evaluatePossibilityOfMixedPrincipals(
        @Nullable final AuthenticationResult context,
        final TicketGrantingTicket ticketGrantingTicket) {
        if (context == null) {
            val error = "Provided authentication result is undefined to evaluate for mixed principals";
            LOGGER.warn(error);
            return null;
        }
        val currentAuthentication = context.getAuthentication();
        if (currentAuthentication != null) {
            val original = ticketGrantingTicket.getAuthentication();
            if (!currentAuthentication.getPrincipal().equals(Objects.requireNonNull(original).getPrincipal())) {
                throw new MixedPrincipalException(currentAuthentication,
                    currentAuthentication.getPrincipal(), original.getPrincipal());
            }
        }
        return currentAuthentication;
    }

    @RequiredArgsConstructor
    private final class ServiceTicketGrantor implements CheckedSupplier<Ticket> {
        private final String ticketGrantingTicketId;
        private final Service service;
        private final @Nullable AuthenticationResult authenticationResult;

View on GitHub (pinned to e7288fc434)