Customizations
A number of interfaces are exposed to enable custom implementations for session storage, certificate validation, and the HTTP-Post form.
Most applications do not require custom implementations. Only consider customizing session storage, certificate validation, or the HTTP-Post form if the defaults do not meet your deployment or security requirements.
ISSOSessionStore
The ISSOSessionStore interface supports storing SAML SSO session state.
The following implementations are provided:
- InMemorySSOSessionStore
- HttpSSOSessionStore
- DatabaseSSOSessionStore
In-Memory Session Store
InMemorySSOSessionStore is the default implementation of ISSOSessionStore and it stores SSO session data in memory.
This is suitable for single server deployments.
For multi-server deployments without sticky sessions, an implementation with a central repository should be used.
ASP.NET Session Store
HttpSSOSessionStore stores the SSO session data in the ASP.NET session. This requires ASP.NET session state to be enabled.
The following example code specifies that SSO session state should be stored in the ASP.NET session.
Database Session Store
DatabaseSSOSessionStore stores the SSO session data in a custom database.
The following example code specifies that SSO session state should be stored in a database.
SSO session data is stored in a single database table, SSOSessions, with the following schema.
| Column Name | Data Type | Notes |
|---|---|---|
| SessionID | nvarchar(256) | Unique identifier for the SSO session data |
| ExpirationDateTime | datetime | UTC date/time when the session identifier expires |
| SessionObject | varbinary(MAX) | Opaque session data stored as a byte array |
The following SQL script creates the SSOSessions table in a SQL Server database.
USE [SAML]
GO
DROP TABLE [dbo].[SSOSessions]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[SSOSessions](
[SessionID] [nvarchar](256) NOT NULL,
[ExpirationDateTime] [datetime] NOT NULL,
[SessionObject] [varbinary](max) NOT NULL,
CONSTRAINT [PK_SSOSessions] PRIMARY KEY CLUSTERED
(
[SessionID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
DatabaseSSOSessionStore expects a web.config connection string named SAML.
For example:
<connectionStrings>
<add name="SAML" providerName="System.Data.SqlClient" connectionString="data source=localhost;database=SAML;uid=saml;pwd=password"/>
</connectionStrings>
Care should be taken to ensure this table does not grow unbounded. Expired rows should be deleted as part of general database maintenance.
IIDCache
The IIDCache interface supports storing SAML identifiers in a cache.
It’s used by the service provider to store SAML assertion identifiers for the lifetime of their validity in order to detect replay attacks.
The following implementations are provided:
- InMemoryIDCache
- DatabaseIDCache
In-Memory ID Cache
InMemoryIDCache is the default implementation of IIDCache and it stores SAML identifiers in memory.
This is suitable for single server deployments.
For multi-server deployments without sticky sessions, an implementation with a central repository should be used.
Database ID Cache
DatabaseIDCache stores the SAML identifiers in a custom database.
The following example code specifies that SAML identifiers should be stored in a database.
SAML identifiers are stored in a single database table, SAMLIdentifiers, with the following schema.
| Column Name | Data Type | Notes |
|---|---|---|
| ID | nvarchar(256) | SAML identifier |
| ExpirationDateTime | datetime | UTC date/time when the SAML identifier expires |
The following SQL script creates the SAMLIdentifiers table in a SQL Server database.
USE [SAML]
GO
DROP TABLE [dbo].[SAMLIdentifiers]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SAMLIdentifiers](
[ID] [nvarchar](256) NOT NULL,
[ExpirationDateTime] [datetime] NOT NULL,
CONSTRAINT [PK_SAMLIdentifiers] PRIMARY KEY CLUSTERED
(
[ID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
DatabaseIDCache expects a web.config connection string named SAML.
For example:
<connectionStrings>
<add name="SAML" providerName="System.Data.SqlClient" connectionString="data source=localhost;database=SAML;uid=saml;pwd=password"/>
</connectionStrings>
Care should be taken to ensure this table does not grow unbounded. Expired rows should be deleted as part of general database maintenance.
ICertificateValidator
The ICertificateValidator interface validates X.509 certificates to ensure they haven't expired or aren't otherwise invalid. This applies to both the local and partner X.509 certificates.
Certificates that fail validation are not used in SAML processing.
The default certificate validator checks for expired certificates which are considered invalid.
The following code turns off expired certificate checking.
SAMLController.CertificateManager.CertificateValidator
.CertificateValidationOptions.EnableNotAfterCheck = false;
The following code removes the certificate validator so no certificate validation is performed.
The following code turns on certificate chain checking for CA-signed certificates.
SAMLController.CertificateManager.CertificateValidator
.CertificateValidationOptions.EnableChainCheck = true;
Certificate Validation Options
CertificateValidationOptions specifies options for the ICertificateValidator implementation.
EnableNotBeforeCheck
Specifies whether checking the certificate's not-before date is enabled.
The default is true.
EnableNotAfterCheck
Specifies whether checking the certificate's not-after date is enabled.
The default is true.
EnableChainCheck
Specifies whether checking the certificate chain is enabled.
This check is ignored for self-signed certificates.
The default is false.
RevocationMode
The certificate revocation mode.
This only applies if EnableChainCheck is true.
The default is X509RevocationMode.NoCheck.
RevocationFlag
Specifies whether certificates in the chain should be checked for revocation.
This only applies if EnableChainCheck is true.
The default is X509RevocationFlag.EndCertificateOnly.
VerificationFlags
Specifies the conditions under which verification of certificates in the certificate chain should be conducted.
This only applies if EnableChainCheck is true.
The default is X509VerificationFlags.NoFlag.
UrlRetrievalTimeout
The maximum amount of time to be spent during online revocation verification or downloading the CRL.
This only applies if EnableChainCheck is true.
The default is 30 seconds.
HTTP-Post Binding
An HTML form template is used by the HTTP-Post binding to send SAML messages.
HTML Template
The default HTML template is:
<html>
<body>
<noscript>
<p>
Since your browser doesn't support JavaScript,
you must press the Continue button to proceed.
</p>
</noscript>
<form id="samlform" action="{url}" method="post" target="{target}">
<div>
{hiddenFormVariables}
</div>
<noscript>
<div>
<input type="submit" value="Continue"/>
</div>
</noscript>
</form>
</body>
<script>
function submitForm() {
document.forms.samlform.submit();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", submitForm);
} else {
submitForm();
}
</script>
</html>
The following substitution parameters are supported.
url
Action URL for the HTTP Post.
target
Target for the HTTP Post (i.e. _self, _blank, _parent or _top).
hiddenFormVariables
Hidden form inputs containing the information to be posted.
HTTP Post Form Options
HTTPPostBinding specifies the following properties.
HTMLFormTarget
HTML form target.
The default is _self.
HTMLFormTemplate
HTML form template.
Content Security Policy
Content Security Policy (CSP) permits the control of resources, including JavaScript, that the browser may load. It helps detect and protect against Cross Site Scripting (XSS) and other forms of attack.
CSP is specified through a Content-Security-Policy header sent to the browser, or through an equivalent element.
By default, no Content-Security-Policy header is included. CSP is available if control of script execution is required for security or compliance reasons. Since the HTML form used for HTTP-Post includes inline JavaScript to automatically submit SAML messages, any CSP policy must allow this script to run for the form to function correctly.
Unsafe Inline
A policy allowing all inline script to load is possible but not recommended.
Nonce
A nonce may be added to the JavaScript to identify it and permit its loading through policy.
<script nonce="2BAC238EBCE24A24ABCC11132361D228">
function submitForm() {
document.forms.samlform.submit();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", submitForm);
} else {
submitForm();
}
</script>
The corresponding policy would include the nonce.
The application is responsible for setting the nonce on a frequent basis and updating the Content-Security-Policy header with this source.
Hash
A hash may be used to identify the JavaScript and permit its loading through policy.
Various 3rd party tools, including the Chrome developer tools, are available for generating the hash.
The corresponding policy would include the hash.
The application is responsible for updating the Content-Security-Policy header with this source.
Trusted Site
Rather than using inline script, a separate script file may be downloaded from a trusted site.
Typically, this will be the application site.
The script file contains the following JavaScript.
function submitForm() {
document.forms.samlform.submit();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", submitForm);
} else {
submitForm();
}
The corresponding policy would include self (i.e. the origin site) as a trusted source.
The application is responsible for updating the HTML template to specify the JavaScript file and updating the Content-Security-Policy header with this source.