The SAML2P component allows for fine control of SAML Response Message validation through the ICustomSamlValidationOverride
extension point.
When a SAML Response is validated a SamlMessageValidationContext
is constructed containing the Parsed SAML response. A series of internal validators are then run on the Context, these validators are SAML2.0 specification compliant. Any errors detected by the internal validators will add a SamlMessageValidationError
to the Errors
collection on the Context. These internal validators cannot be modified, but any errors they add to the SamlMessageValidationContext
can be manually ignored via the extension point ICustomSamlValidationOverride
. Custom validators can also be run in the ICustomSamlValidationOverride
and can add new Errors to the Errors
collection. Implementation of this is left up to individual developers.
This functionality is designed to allow full integration with opinionated SAML2.0 providers who aren't adhering to the SAML 2.0 specification. This should not be required by most SAML IdPs. Any usage of this overriding functionality should be done with caution and avoided when possible. If you are unsure if this functionality is required, please contact our support desk at support@rocksolidknowledge.com .
Improper usage of this extensibility point may leave your ServiceProvider vulnerable to attacks.
ICustomSamlValidationOverride
public interface ICustomSamlValidationOverride
{
Task ValidateSamlSSOResponse(ISamlMessageValidationContext samlMessageValidationContext);
}
SamlMessageValidationError
SamlMessageValidationError
is the base type of all Errors. Errors for each validator also inherit from a type specific to that validator e.g. AssertionAuthStatementError
.
A SamlMessageValidationError
has the following properties.
Type
:Validator
The validator that added this error to the context.string
:Error
The Error type. A full list of Errors by Validator can be found under theSamlMessageValidationErrors
static class.string
:ErrorDescription
A description of the Error.bool
:Ignore
Whether to ignore this error when determining if the SAML Message is valid. Defaults tofalse
string
:ServiceProviderEntityId
The EntityId of the Service Provider the validation is taking place for. If you have multiple ServiceProviders configured for different SAML IdPs then you can use this to filter Errors for specific ServiceProviders.
Example ICustomSamlValidationOverride
A ICustomSamlValidationOverride
can be created that can control logic to either ignore errors for specific ServiceProviders or run custom validation code.
We recommend extending our base abstract class BaseCustomSamlValidationOverride
overriding the methods you require rather than implementing the interface yourself.
Below is a simple example implementation that will cause all InvalidAssertionConsumerEndpoint
for the ServiceProvider where the entityId is "https://localhost:44300/saml2" to be ignored. A custom ISamlMessageValidator validator is then run, if an error is detected in the custom validator a new SamlMessageValidationError
should be added to the errors collection on the context. An un-ignored error in the context will cause the message validation to fail.
public interface ICustomAcsValidator : ISamlMessageValidator { }
public class CustomAcsValidator : ICustomAcsValidator
{
public Task Validate(ISamlMessageValidationContext samlMessageValidationContext)
{
//Run custom ACS validation logic
}
}
public class DefaultCustomSamlValidationOverride : BaseCustomSamlValidationOverride
{
private readonly ICustomAcsValidator acsValidator;
public DefaultCustomSamlValidationOverride(ICustomAcsValidator acsValidator)
{
this.acsValidator = acsValidator ?? throw new ArgumentNullException(nameof(acsValidator));
}
public async Task ValidateSamlResponse(ISamlMessageValidationContext samlMessageValidationContext)
{
samlMessageValidationContext.IgnoreAll<InvalidAssertionConsumerEndpoint>( x => x.ServiceProviderEntityId == "https://localhost:44300/saml2");
await acsValidator.Validate(samlMessageValidationContext);
}
}
SAML Message Validation Errors
The following is a list of every SamlMessageValidationError
that can be added to a SamlMessageValidationContext
Assertion Validation Errors
AssertionXmlMissing
: Error added when the SAMLResponse does not contain an Assertion.AssertionAudienceInvalid
: Error added when the ServiceProvider does not meet the audience restriction on the SAMLResponse assertion.AssertionNotBefore
: Error added when the SAMLResponse assertion NotBefore value is before the current server time.AssertionNotOnOrAfter
: Error added when the SAMLResponse assertion NotOnOrAfter value is on or after the current server time.AssertionNotSigned
: Error added when the SAMLResponse assertion is not signed, but the WantAssertionsSigned flag is set totrue
.AssertionInResponseToInvalid
: Error added when the Assertion InResponseTo value does not match the SAMLRequest ID.ResponseInResponseToMissing
: Error added when the SAMLResponse assertion does not contain an InResponseTo value but the Assertion SubjectSaml2SubjectConfirmationData
InResponseTo value does.AssertionSubjectNotBefore
: Error added when the SAMLResponse Assertion Subject NotBefore value is before the current server time.AssertionSubjectNotOnOrAfter
: Error added when the SAMLResponse Assertion Subject NotOnOrAfter value is on or after the current server time.
Assertion Auth Statement Validation Errors
AssertionAuthStatementMissing
: Error added when the SAMLResponse does not contain an Assertion Auth Statement. Successful responses must contain exactly one Auth Statement.AssertionAuthStatementTooMany
: Error added when the SAMLResponse contains more than one Assertion Auth Statement. Successful responses must contain exactly one Auth Statement.AuthStatementContextNotMet
: Error added when the SAMLResponse assertion does not meet theRequestedAuthenticationContext
on the SAML options.
Encrypted Assertion Validator Errors
EncryptedAssertionsRequired
: Error added when the SAMLResponse does not contain an Encrypted Assertion butSamlSpOptions.RequireEncryptedAssertions
istrue
.EncryptedAssertionsMissingCertificate
: Error when the SAMLResponse contains an Encrypted Assertion butSamlSpOptions.EncryptionCertificate
is null.EncryptionCertificatePrivateKey
: Error added when the SAMLResponse contains an Encrypted Assertion butSamlSpOptions.EncryptionCertificate
does not have a private key.EncryptedAssertionIncorrectNamespace
: Error added when the SAMLResponse contains an Encrypted Assertion but with an incorrect namespace.EncryptedAssertionIncorrectName
: Error added when the SAMLResponse contains an Encrypted Assertion but with an incorrect name.
IdentityProvider Validator Errors
InvalidIdentityProvider
: Error added when the SAMLResponse Issuer does not match the configuredSaml2pAuthenticationOptions.IdentityProviderOptions
.
IssueInstant Validator Errors
IssueInstantMissing
: Error added when the SAMLResponse does not contain an IssueInstant.IssueInstantInvalid
: Error added when the SAMLResponse contains an IssueInstant but it cannot be parsed.IssueInstantPast
: Error added when the SAMLResponse contains an IssueInstant in the past beyond the allowedSamlSpOptions.TimeComparisonTolerance
andSamlOptions.MessageTrustLength
tolerance.IssueInstantFuture
: Error added when the SAMLResponse contains an IssueInstant in the future beyond the allowedSamlSpOptions.TimeComparisonTolerance
.
SamlServiceProviderValidatorError Validator Errors
InvalidAssertionConsumerEndpoint
: Error added when the SAMLResponse Destination does not match the configured ServiceProvider AssertionConsumerService Url.
Signature Validator Errors
SamlResponseSignatureRequired
: Error added when the SAMLResponse does not contain a signature.SignatureAlgorithmMissing
: Error added when the SAMLResponse does not contain a signature algorithm.SigningCertificateCollectionEmpty
: Error added when the SAML ServiceProviderSamlSpOptions.SigningCertificate
collection is empty.SignatureInvalid
: Error added when the SAMLResponse outer message signature is invalid.AssertionSignatureInvalid
: Error added when the SAMLResponse Assertion signature is invalid.