Skip to content

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.

using ComponentSpace.SAML2.Session;

SAMLController.SSOSessionStore = new HttpSSOSessionStore();

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.

using ComponentSpace.SAML2.Session;

SAMLController.SSOSessionStore = new DatabaseSSOSessionStore();

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.

using ComponentSpace.SAML2.Cache;

SAMLController.IDCache = new DatabaseIDCache();

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.

SAMLController.CertificateManager.CertificateValidator = null;

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.

Content-Security-Policy: script-src 'unsafe-inline'

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.

Content-Security-Policy: script-src 'nonce-2BAC238EBCE24A24ABCC11132361D228'

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.

Content-Security-Policy: script-src 'sha256-oJqv2rhhrRCF1O504qOiwpGkD/R3s5/Btx1EFtIkfcU='

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.

Content-Security-Policy: script-src 'self'

The application is responsible for updating the HTML template to specify the JavaScript file and updating the Content-Security-Policy header with this source.