@Override
    public AuthenticationResult build(final Service service) throws Throwable {
        val authentication = buildAuthentication(principalElectionStrategy);
        if (authentication == null) {
            LOGGER.info("Authentication result cannot be produced because no authentication is recorded into in the chain");
            return null;
        }
        LOGGER.trace("Building an authentication result for authentication [{}] and service [{}]", authentication, service);
        val authenticationResult = new DefaultAuthenticationResult(authentication, service);
        authenticationResult.setCredentialProvided(!this.providedCredentials.isEmpty());
        return authenticationResult;
    }
Principal id is and must be enforced to be the same for all authentications.
Based on that restriction, it's safe to grab the first principal id in the chain
when composing the authentication chain for the caller.
core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/DefaultAuthenticationResultBuilder.java