apereo/cas · error · AuthenticationException

Unable to determine authentication from the request context

Error message

Unable to determine authentication from the request context

What it means

BaseAcceptableUsagePolicyRepository.verify() retrieves the current Authentication from the webflow request context to check the principal's AUP acceptance. With no authentication in scope it cannot evaluate the policy and throws AuthenticationException.

Solutions

  1. Move the AUP verification state after authentication in the login webflow so an Authentication exists in the context
  2. Ensure the user completes a fresh login (valid flow execution) rather than reusing an expired session
  3. In custom integrations, populate the context first via WebUtils.putAuthentication(context, authentication) before calling verify()
  4. Check any custom AcceptableUsagePolicyRepository overrides that call verify() prematurely

Example fix

// before
val status = aupRepository.verify(requestContext);
// after
if (WebUtils.getAuthentication(requestContext) == null) {
    throw new IllegalStateException("AUP verification requires an authenticated principal; place AUP state after authentication");
}
val status = aupRepository.verify(requestContext);
Defensive patterns

Strategy: type-guard

Validate before calling

if (WebUtils.getAuthentication(requestContext) == null) {
    throw new IllegalStateException("AUP state must run after authentication");
}

Type guard

Authentication authn = WebUtils.getAuthentication(requestContext);
boolean readyForAupCheck = authn != null && authn.getPrincipal() != null;

Try / catch

try {
    return aupRepository.verify(requestContext);
} catch (AuthenticationException e) {
    logger.warn("AUP verification without authentication; restart login flow");
    return AcceptableUsagePolicyStatus.denied(principal-less flow);
}

Prevention

When it happens

Trigger: The AUP webflow action/repositories' verify() runs during a flow where WebUtils.getAuthentication(requestContext) is null — e.g. AUP verification invoked outside the authenticated portion of the login flow, after session/context loss, or in a custom flow that skipped authentication.

Common situations: Custom webflow states calling the AUP repository before authentication completes; AUP verification triggered via a direct endpoint without flow authentication; expired sessions resuming a stale execution; ordering issues where the AUP state was placed before credential validation.

Understand the failure class

Related errors


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

Appendix: source

Thrown at support/cas-server-support-aup-core/src/main/java/org/apereo/cas/aup/BaseAcceptableUsagePolicyRepository.java:36

 * @author Misagh Moayyed
 * @since 4.2.0
 */
@Slf4j
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class BaseAcceptableUsagePolicyRepository implements AcceptableUsagePolicyRepository {
    @Serial
    private static final long serialVersionUID = 1883808902502739L;

    /**
     * Acceptable usage policy properties.
     */
    protected final AcceptableUsagePolicyProperties aupProperties;
    
    @Override
    public AcceptableUsagePolicyStatus verify(final RequestContext requestContext) throws Throwable {
        val authentication = WebUtils.getAuthentication(requestContext);
        if (authentication == null) {
            throw new AuthenticationException("Unable to determine authentication from the request context");
        }
        val principal = authentication.getPrincipal();

        if (isUsagePolicyAcceptedBy(principal)) {
            LOGGER.debug("Acceptable usage policy has been accepted by [{}]", principal.getId());
            return AcceptableUsagePolicyStatus.accepted(principal);
        }

        LOGGER.info("Acceptable usage policy has not been accepted by [{}]", principal.getId());
        return AcceptableUsagePolicyStatus.denied(principal);
    }

    /**
     * Determines whether the user has accepted the usage policy.
     * Looks into the attributes collected by the principal to find the correct attribute, specified in settings..
     * If the attribute contains {@code true}, then the policy is determined as accepted.
     *
     * @param principal the principal

View on GitHub (pinned to e7288fc434)