Class SamlAssertionValidator
<samlp:Response> document and produces a ClaimsPrincipal marked
with issuerType=SAML.
Wraps OpenSAML 5.x's parser, unmarshaller, signature validator, and (optionally) assertion decrypter. The validator enforces:
- Mandatory assertion signature — every assertion must carry its own enveloped signature.
A response that signs only the
<Response>envelope (and not the assertion) is rejected as unsigned; response-envelope-level signatures are not supported. - Strict signature-algorithm allowlist — only
rsa-sha256andecdsa-sha256are accepted out of the box. SHA-1 is permanently rejected. The referenceDigestMethodis separately allowlisted (SHA-256/384/512), so a SHA-1 digest is rejected even under a SHA-256 signature. - Response status — the
<samlp:Status>must report theSuccessstatus code. - Clock skew — defaults to 60 seconds tolerance on
NotBefore/NotOnOrAfter; capped at 300 seconds. - Audience restriction —
<AudienceRestriction>must list the configured SP entity ID. - Bearer subject confirmation — enforced whenever a
recipient(the SP ACS URL) is known, either becauseSamlAssertionValidator.Builder.recipient(String)was configured on this validator or because the caller invokedvalidate(String, String)with one.SamlAuthFilteralways callsvalidate(String, String)with the ACS URL derived from the current request, so a validator reached only through the filter can never skip this check. When enforced, the assertion must carry abearer<SubjectConfirmation>whose<SubjectConfirmationData>matches the expectedRecipient, is within itsNotBefore/NotOnOrAfterwindow, and satisfies the configuredInResponseTo/Addressexpectations. A validator used standalone (not throughSamlAuthFilter) skips this check unlessSamlAssertionValidator.Builder.recipient(String)is configured — that mode is not safe for browser-SSO ACS endpoints, since nothing then binds the assertion to a specific recipient. - One-time use — each assertion ID is recorded in a
ReplayCacheand a second presentation of the same ID is rejected. The check is fail-closed: if the cache cannot answer, the assertion is rejected. An assertion whose validity window is unbounded — carrying neither aConditions/NotOnOrAfternor a bearerSubjectConfirmationData/NotOnOrAfter— is rejected outright, and the cache record is retained until the resolvedNotOnOrAfter(plus clock skew) rather than a short default window that would later expire and re-open replay. - Encrypted assertions — if the response contains
<EncryptedAssertion>, adecryptionCredentialmust be configured.
Marker claim
The returned ClaimsPrincipal is annotated with issuerType=SAML so downstream code
can distinguish SAML-derived principals from JWT-derived principals without resorting to a subclass:
Builder usage
This recipe builds a standalone validator with no SamlAssertionValidator.Builder.recipient(String) configured, so
bearer subject-confirmation is not enforced. It is safe for assertion-only / non-browser callers that
validate an assertion outside of an ACS redirect. Deploying it behind SamlAuthFilter for
browser-SSO is always safe regardless: the filter derives the ACS recipient from the request and calls
validate(String, String), which enforces bearer confirmation for that call no matter how this
validator was built.
See Also:
- Since:
- 10.0.0
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringMarker claim name on the returnedClaimsPrincipal.static final StringMarker claim value identifying the principal as SAML-issued. -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedConstructor. -
Method Summary
Modifier and TypeMethodDescriptioncreate()Static creator.Returns the configured signature algorithm allowlist.Returns the configured clock-skew tolerance.Returns the expected IdP<Issuer>value.Returns the SP entity ID this validator enforces in<AudienceRestriction>.Validates the supplied SAML 2.0<samlp:Response>XML and returns the resolved principal.Validates the supplied SAML 2.0<samlp:Response>XML, enforcing bearer<SubjectConfirmation>against the givenrecipientfor this call.
-
Field Details
-
ISSUER_TYPE_CLAIM
Marker claim name on the returnedClaimsPrincipal.- See Also:
-
ISSUER_TYPE_SAML
Marker claim value identifying the principal as SAML-issued.- See Also:
-
-
Constructor Details
-
SamlAssertionValidator
Constructor.- Parameters:
b- The builder to read configuration from.
-
-
Method Details
-
create
Static creator.- Returns:
- A new builder.
-
getSpEntityId
Returns the SP entity ID this validator enforces in<AudienceRestriction>.- Returns:
- The configured SP entity ID.
-
getExpectedIssuer
Returns the expected IdP<Issuer>value.- Returns:
- The expected issuer.
-
getAlgorithms
Returns the configured signature algorithm allowlist.- Returns:
- The unmodifiable allowlist.
-
getClockSkew
Returns the configured clock-skew tolerance.- Returns:
- The clock skew.
-
validate
Validates the supplied SAML 2.0<samlp:Response>XML and returns the resolved principal.- Parameters:
xml- The full XML payload (already base64-decoded; already URL-decoded and inflated for the REDIRECT binding). Must be a<samlp:Response>envelope.- Returns:
- A
ClaimsPrincipalcarrying the IdP-supplied claims plus theissuerType=SAMLmarker. - Throws:
AuthenticationException- If the response cannot be parsed or validation fails.
-
validate
Validates the supplied SAML 2.0<samlp:Response>XML, enforcing bearer<SubjectConfirmation>against the givenrecipientfor this call.Unlike
validate(String), bearer subject-confirmation is always enforced here —recipientoverrides whateverSamlAssertionValidator.Builder.recipient(String)this validator was built with (including unset).SamlAuthFiltercalls this overload with the ACS URL derived from the current request so that a validator built withoutSamlAssertionValidator.Builder.recipient(String)configured still rejects an assertion bearer-confirmed to a different endpoint on the filter path.- Parameters:
xml- The full XML payload (already base64-decoded; already URL-decoded and inflated for the REDIRECT binding). Must be a<samlp:Response>envelope.recipient- The expectedRecipient(this SP's ACS URL) for bearer subject-confirmation. Must not benull or blank.- Returns:
- A
ClaimsPrincipalcarrying the IdP-supplied claims plus theissuerType=SAMLmarker. - Throws:
AuthenticationException- If the response cannot be parsed or validation fails.
-