protected void validateSamlSSOResponse(final Response response, final SAML2MessageContext context,
                                           final SignatureTrustEngine engine, final Decrypter decrypter) {

        final List<SAMLException> errors = new ArrayList<>();
        for (val assertion : response.getAssertions()) {
            if (!assertion.getAuthnStatements().isEmpty()) {
                try {
                    validateAssertion(assertion, context, engine, decrypter);
                } catch (final SAMLException e) {
                    logger.error("Current assertion validation failed, continue with the next one", e);
                    errors.add(e);
                    continue;
                }
                context.setSubjectAssertion(assertion);
                break;
            }
        }

        if (!errors.isEmpty()) {
            throw errors.get(0);
        }
        if (context.getSubjectAssertion() == null) {
            throw new SAMAssertionSubjectException("No valid subject assertion found in response");
        }

        // We do not check EncryptedID here because it has been already decrypted and stored into NameID
        val subjectConfirmations = context.getSubjectConfirmations();
        var configContext = context.getConfigurationContext();

        if (subjectConfirmations == null || subjectConfirmations.isEmpty()) {
            if (configContext.getNameIdAttribute() != null) {
                logger.debug("NameID will be determined from attribute {}", configContext.getNameIdAttribute());
            } else {
                XSString nameIdentifier = (NameID) context.getSAMLSubjectNameIdentifierContext().getSubjectNameIdentifier();
                if ((nameIdentifier == null || nameIdentifier.getValue() == null) && context.getBaseID() == null
                    && (subjectConfirmations == null || subjectConfirmations.isEmpty())) {
                    throw new SAMLException(
                        "Subject NameID, BaseID and EncryptedID cannot be all null at the same time without Subject Confirmations.");
                }
            }
        }
    }
Validates the SAML SSO response by finding a valid assertion with authn statements.
Populates the {@link SAML2MessageContext} with a subjectAssertion and a subjectNameIdentifier.

@param response  the response
@param context   the context
@param engine    the engine
@param decrypter the decrypter
pac4j-saml/src/main/java/org/pac4j/saml/sso/impl/SAML2AuthnResponseValidator.java