Search in sources :

Example 1 with BaseID

use of org.opensaml.saml.saml2.core.BaseID in project pac4j by pac4j.

the class SAML2DefaultResponseValidator method validateSubject.

/**
 * Validate the given subject by finding a valid Bearer confirmation. If the subject is valid, put its nameID in the context.
 * <p>
 * NameID / BaseID / EncryptedID is first looked up directly in the Subject. If not present there, then all relevant
 * SubjectConfirmations are parsed and the IDs are taken from them.
 *
 * @param subject   The Subject from an assertion.
 * @param context   SAML message context.
 * @param decrypter Decrypter used to decrypt some encrypted IDs, if they are present.
 *                  May be {@code null}, no decryption will be possible then.
 */
@SuppressWarnings("unchecked")
protected final void validateSubject(final Subject subject, final SAML2MessageContext context, final Decrypter decrypter) {
    boolean samlIDFound = false;
    // Read NameID/BaseID/EncryptedID from the subject. If not present directly in the subject, try to find it in subject confirmations.
    NameID nameIdFromSubject = subject.getNameID();
    final BaseID baseIdFromSubject = subject.getBaseID();
    final EncryptedID encryptedIdFromSubject = subject.getEncryptedID();
    // Encrypted ID can overwrite the non-encrypted one, if present
    final NameID decryptedNameIdFromSubject = decryptEncryptedId(encryptedIdFromSubject, decrypter);
    if (decryptedNameIdFromSubject != null) {
        nameIdFromSubject = decryptedNameIdFromSubject;
    }
    // At least one should be present but we don't care at this point.
    if (nameIdFromSubject != null || baseIdFromSubject != null) {
        context.getSAMLSubjectNameIdentifierContext().setSubjectNameIdentifier(nameIdFromSubject);
        context.setBaseID(baseIdFromSubject);
        samlIDFound = true;
    }
    for (final SubjectConfirmation confirmation : subject.getSubjectConfirmations()) {
        if (SubjectConfirmation.METHOD_BEARER.equals(confirmation.getMethod()) && isValidBearerSubjectConfirmationData(confirmation.getSubjectConfirmationData(), context)) {
            NameID nameIDFromConfirmation = confirmation.getNameID();
            final BaseID baseIDFromConfirmation = confirmation.getBaseID();
            final EncryptedID encryptedIDFromConfirmation = confirmation.getEncryptedID();
            // Encrypted ID can overwrite the non-encrypted one, if present
            final NameID decryptedNameIdFromConfirmation = decryptEncryptedId(encryptedIDFromConfirmation, decrypter);
            if (decryptedNameIdFromConfirmation != null) {
                nameIDFromConfirmation = decryptedNameIdFromConfirmation;
            }
            if (!samlIDFound && (nameIDFromConfirmation != null || baseIDFromConfirmation != null)) {
                context.getSAMLSubjectNameIdentifierContext().setSubjectNameIdentifier(nameIDFromConfirmation);
                context.setBaseID(baseIDFromConfirmation);
                context.getSubjectConfirmations().add(confirmation);
                samlIDFound = true;
            }
            if (!samlIDFound) {
                logger.warn("Could not find any Subject NameID/BaseID/EncryptedID, neither directly in the Subject nor in any Subject " + "Confirmation.");
            }
            return;
        }
    }
    throw new SAMLSubjectConfirmationException("Subject confirmation validation failed");
}
Also used : BaseID(org.opensaml.saml.saml2.core.BaseID) SubjectConfirmation(org.opensaml.saml.saml2.core.SubjectConfirmation) NameID(org.opensaml.saml.saml2.core.NameID) EncryptedID(org.opensaml.saml.saml2.core.EncryptedID) SAMLSubjectConfirmationException(org.pac4j.saml.exceptions.SAMLSubjectConfirmationException)

Example 2 with BaseID

use of org.opensaml.saml.saml2.core.BaseID in project pac4j by pac4j.

the class SAML2DefaultResponseValidator method validateSamlSSOResponse.

/**
 * 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
 */
protected final void validateSamlSSOResponse(final Response response, final SAML2MessageContext context, final SignatureTrustEngine engine, final Decrypter decrypter) {
    final List<SAMLException> errors = new ArrayList<>();
    for (final Assertion 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
    final List<SubjectConfirmation> subjectConfirmations = context.getSubjectConfirmations();
    final NameID 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 if there are no Subject Confirmations.");
    }
}
Also used : SAMAssertionSubjectException(org.pac4j.saml.exceptions.SAMAssertionSubjectException) SubjectConfirmation(org.opensaml.saml.saml2.core.SubjectConfirmation) NameID(org.opensaml.saml.saml2.core.NameID) ArrayList(java.util.ArrayList) EncryptedAssertion(org.opensaml.saml.saml2.core.EncryptedAssertion) Assertion(org.opensaml.saml.saml2.core.Assertion) SAMLException(org.pac4j.saml.exceptions.SAMLException)

Aggregations

NameID (org.opensaml.saml.saml2.core.NameID)2 SubjectConfirmation (org.opensaml.saml.saml2.core.SubjectConfirmation)2 ArrayList (java.util.ArrayList)1 Assertion (org.opensaml.saml.saml2.core.Assertion)1 BaseID (org.opensaml.saml.saml2.core.BaseID)1 EncryptedAssertion (org.opensaml.saml.saml2.core.EncryptedAssertion)1 EncryptedID (org.opensaml.saml.saml2.core.EncryptedID)1 SAMAssertionSubjectException (org.pac4j.saml.exceptions.SAMAssertionSubjectException)1 SAMLException (org.pac4j.saml.exceptions.SAMLException)1 SAMLSubjectConfirmationException (org.pac4j.saml.exceptions.SAMLSubjectConfirmationException)1