Working with SHA-256

In order to sign and validate an SHA-256 signature, please ensure:
1. If you use .NET 4.5

Add a reference to the System.Deployment assembly.
Add the following code segment to your application’s bootstrap:
C#:

using System.Security.Cryptography;
using System.Deployment.Internal.CodeSigning;
...
protected void Application_Start(object sender, EventArgs e)
{
	Enable SHA-256 XML signature support.
	CryptoConfig.AddAlgorithm(
		 typeof(RSAPKCS1SHA256SignatureDescription),
		 "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
};

2. If you use .NET 3.5 and 4.0

Make sure the following exists in your machine.config file for corresponding .NET Framework (both 32 and 64 bits)

<mscorlib>
<cryptographySettings>
<cryptoNameMapping>
<cryptoClasses>
<cryptoClass RSASHA256SignatureDescription=”Security.Cryptography.RSAPKCS1SHA256SignatureDescription, Security.Cryptography, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ />
</cryptoClasses>
<nameEntry name=”http://www.w3.org/2001/04/xmldsig-more#rsa-sha256” />
</cryptoNameMapping>
</cryptographySettings>
</mscorlib>

Download the security extension library at: http://clrsecurity.codeplex.com/
Add reference to the newly downloaded assembly

Example of HttpResponse or HttpResponseBase object

Question: I have an AuthnRequest I’d like to send to IDP. What is the parameter Response from SendHttpPost method of Request class ?What is the relay state ?

Answer: That is the HttpResponse or HttpResponseBase object, usually Page.Response in WebForms. The relay state is your defined value. You can use your orginal URL as the relaystate. Here is an example of how to use that method:

<pre>using System;
using System.Web.Configuration;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Web;
using ComponentPro.Saml2;
namespace SamlIdPInitiated.IdentityProvider
{
    public partial class Service : System.Web.UI.Page
    {
        // Get consumer service URL from the application settings.
        private static readonly string ConsumerServiceUrl = WebConfigurationManager.AppSettings["ConsumerServiceUrl"];
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            try
            {
                // Extract the SP target url.
                string targetUrl = Request.QueryString["spUrl"];
                // Validate it.
                if (string.IsNullOrEmpty(targetUrl))
                {
                    return;
                }
                // Create a SAML response object.
                ComponentPro.Saml2.Response samlResponse = new ComponentPro.Saml2.Response();
                // Assign the consumer service url.
                samlResponse.Destination = ConsumerServiceUrl;
                Issuer issuer = new Issuer(GetAbsoluteUrl("~/"));
                samlResponse.Issuer = issuer;
                samlResponse.Status = new Status(SamlPrimaryStatusCode.Success, null);
                Assertion samlAssertion = new Assertion();
                samlAssertion.Issuer = issuer;
                // Use the local user's local identity.
                Subject subject = new Subject(new NameId(User.Identity.Name));
                SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SamlSubjectConfirmationMethod.Bearer);
                SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData();
                subjectConfirmationData.Recipient = ConsumerServiceUrl;
                subjectConfirmation.SubjectConfirmationData = subjectConfirmationData;
                subject.SubjectConfirmations.Add(subjectConfirmation);
                samlAssertion.Subject = subject;
                // Create a new authentication statement.
                AuthnStatement authnStatement = new AuthnStatement();
                authnStatement.AuthnContext = new AuthnContext();
                authnStatement.AuthnContext.AuthnContextClassRef = new AuthnContextClassRef(SamlAuthenticationContext.Password);
                samlAssertion.Statements.Add(authnStatement);
                // If you need to add custom attributes, uncomment the following code
                // #region Custom Attributes
                // AttributeStatement attributeStatement = new AttributeStatement();
                // attributeStatement.Attributes.Add(new ComponentPro.Saml2.Attribute("email", SamlAttributeNameFormat.Basic, null,
                                                                                             // "john@test.com"));
                // attributeStatement.Attributes.Add(new ComponentPro.Saml2.Attribute("FirstName", SamlAttributeNameFormat.Basic, null,
                                                                                             // "John"));
                // attributeStatement.Attributes.Add(new ComponentPro.Saml2.Attribute("LastName", SamlAttributeNameFormat.Basic, null,
                                                                                             // "Smith"));
                // // Insert a custom token key to the SAML response.
                // attributeStatement.Attributes.Add(new ComponentPro.Saml2.Attribute("CustomTokenForVerification", SamlAttributeNameFormat.Basic, null,
                                                                                             // "YourEncryptedTokenHere"));
                // samlAssertion.Statements.Add(attributeStatement);
                // #endregion
                // Define ENCRYPTEDSAML preprocessor flag if you wish to encrypt the SAML response.
#if ENCRYPTEDSAML
                // Load the certificate for the encryption.
                // Please make sure the file is in the root directory.
                X509Certificate2 encryptingCert = new X509Certificate2(Path.Combine(HttpRuntime.AppDomainAppPath, "EncryptionX509Certificate.cer"), "password");
                // Create an encrypted SAML assertion from the SAML assertion we have created.
                EncryptedAssertion encryptedSamlAssertion = new EncryptedAssertion(samlAssertion, encryptingCert, new System.Security.Cryptography.Xml.EncryptionMethod(SamlKeyAlgorithm.TripleDesCbc));
                // Add encrypted assertion to the SAML response object.
                samlResponse.Assertions.Add(encryptedSamlAssertion);
#else
                // Add assertion to the SAML response object.
                samlResponse.Assertions.Add(samlAssertion);
#endif
                // Get the previously loaded certificate.
                X509Certificate2 x509Certificate = (X509Certificate2)Application[Global.CertKeyName];
                // Sign the SAML response with the certificate.
                samlResponse.Sign(x509Certificate);
                // Send the SAML response to the service provider.
                samlResponse.SendHttpPost(Response.OutputStream, ConsumerServiceUrl, targetUrl);
            }
            catch (Exception exception)
            {
                Trace.Write("IdentityProvider", "An Error occurred", exception);
            }
        }
        private string GetAbsoluteUrl(string relativeUrl)
        {
            Uri u = new Uri(Request.Url, ResolveUrl(relativeUrl));
            return u.ToString();
        }
    }
}</pre>
<span style="line-height: 1.714285714; font-size: 1rem;">

Verify signature on SAML assertion

This example code verifies SAML response using UltimateSAML. It helps verify nested SAML assertion signature inside a response.

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(samlResponseXmlToVerify);

XmlDocument xmlDocumentMetadata = new XmlDocument();
xmlDocumentMetadata.Load(samlMetadataXmlToExtractCertData);

// Load the SAML response from the XML document.
Response samlResponse = new Response(xmlDocument.DocumentElement);

// Is it signed?
if (samlResponse.IsSigned())
{
    // Validate the SAML response with the certificate.
    if (!samlResponse.Validate(xmlDocumentMetadata.DocumentElement))
    {
        throw new ApplicationException("SAML response signature is not valid.");
    }
} ;

Check the following link for more detailed online example

http://www.componentpro.com/doc/saml/ComponentPro.Saml.SignableSamlObject.Validate().htm

SP-Initiated Web Applications

Single Sign-On Introduction

In this SP-Initiated SSO scenario, a user browses to the SP site and attempts to access a protected resource on the SP site. If the user is not logged in, the SP asks the user to log in at the IdP site. When the authentication is complete the user is redirected back to the SP.

Processing Steps:

  1. A user request access to a protected resource on the SP site. If the user is not logged in, SP redirects him or her to the IdP to handle authentication. SP also sends an authentication request to the IdP site.
  2. The user presents his or her credentials to log in at the IdP.
  3. If the user credentials are correct, IdP sends a SAML response containing the authentication assertion and any attributes back to the SP site.
  4. The SP validates the message. If the signature and assertion is valid, the SP uses the information in the SAML Response to perform an automatic login.

Single Logout Introduction

In this SP-Initiated SLO scenario, a user clicks on a link at the SP site to log out of the current SP site, the IdP site and all the other participating SP sites.

Service Provider Example Web Application

After successfully installing the UltimateSaml setup package you will see two web sample projects in folderSamples\Saml\Web\CS\Saml2SPInitiated for C# and Samples\Saml\Web\VB\Saml2SPInitiated for VB.NET. To run these web sample projects, open the solution file Saml2SPInitiated_XXXX.sln, and then press F5 in the Visual Studio IDE.

This sample is configured to run at port 1426 (you can easily change the port number in the project property page). The identity provider web application, in conjunction with Service Provider web application, demonstrates IdP initiated single sign-on. Firstly, you can either login to the local system with the user name suser and a password of password or follow the steps below:

SPInit

  1. Select the binding to use when communicating between the Service Provider web application and Identity Provider web application.
  2. Select the binding to use when communicating between the Identity Provider web application and Service Provider web application.
  3. Click on the Next button.
  4. You should then be presented with the Identity Provider login page as you will be logging in at the Identity Provider web application, not the Service Provider web applicationSPloggedin

You have successfully completed a SAML 2.0 Single Sign-On and are logged in at the Service Provider with your Identity Provider user name.

NOTE for step 1 and 2: The user experience should be the same regardless of the binding selected. The only time when this is not the case is if the HTTP POST binding is selected and Javascript is disabled in which case the user will be presented with an intermediate form and a button they need to click.

How to configure?

You can easily configure the Service Provider web application by modifying the settings within its web.config file’s <appSettings> section:

Identity Provider Example Web Application

This sample is configured to run at port 1425 (you can easily change the port number in the project property page). The identity provider web application, in conjunction with Service Provider web application, demonstrates IdP initiated single sign-on. You can login to the local system with the user name iuser and a password of password.

How to configure?

You can easily configure the ID Provider web application by modifying the settings within its web.config file’s <appSettings> section:

Cross-domain Single Sign-On

The cross-domain SSO live demo applications are at http://idp.codeultimate.com (Identity Provider),http://sp.codeultimate.com (Service Provider 1), and http://sp2.codeultimate.com (Service Provider 2). The following steps illustrate how these cross-domain applications work:

  1. Open http://sp.codeultimate.com
  2. Click on the Next button; you will be redirected to IdP site to login
  3. At the IdP’s login page, type iuser and password
  4. You are now redirected back to the SP’s homepage
  5. On the address bar of the browser, type http://sp2.codeultimate.com and press Enter
  6. You will be represented with the homepage of the SP2
  7. Click on the Next button; you will see that you are logged in at the SP2 with user id iuser
  8. Now you see how to log into a single IdP and let users use other Service Providers without asking users to log in multiple times

The code of these cross-domain SSO live demo applications is available in the setup package. After installing the setup package, you can see three sample projects in folder Samples\Saml\Web\CS\Saml2MultipleSPsfor C# and Samples\Saml\Web\VB\Saml2MultipleSPs for VB.NET. To open the Cross-domain SSO demo applications, double click on the solution file named Saml2MultipleSPs_XXXX.sln.

Creating and sending an AuthnRequest

Today we will introduce an example on how to create an AuthnRequest and send it to your IdentityProvider using our Ultimate SAML component:

AuthnRequest request = new AuthnRequest();
request.IsPassive = false;
request.ProtocolBinding = SamlBindingUri.HttpPost;
request.AssertionConsumerServiceURL = "your url";

request.Issuer = new Issuer();
request.Issuer.NameIdentifier = "your name identifier";

request.NameIdPolicy = new NameIdPolicy();
request.NameIdPolicy.SpNameQualifier = "moodle.sp.myname";
request.NameIdPolicy.AllowCreate = true;
request.NameIdPolicy.Format = SamlNameIdentifierFormat.Persistent;

request.RequestedAuthnContext = new RequestedAuthnContext();
request.RequestedAuthnContext.Comparison = SamlAuthenticationContextComparison.Exact;
request.RequestedAuthnContext.AuthenticationContexts.Add(new AuthnContextClassRef(SamlAuthenticationContext.PasswordProtectedTransport));

request.SendHttpPost(Response, "http://mybaseurl", "my_relay_state");

Ultimate SAML now supports ASP.NET MVC

MVC support feature and an illustrative example have been requested by so many customers and today we would like to introduce the IdP-Initiated SAML MVC application example using the latest version of the Ultimate SAML component.

To open the MVC example solution, navigate to “Samples\Mvc\Saml\CS\Saml2IdpInitiatedMvc” and double-click on the solution file. The example is very similar to the ASP.NET Saml2IdPInitiated. They share the same logic to authenticate users, check SAML data and navigate to the provider sites. The only difference in SAML code segments is that the MVC’s apps use overloads that have the HttpRequestBase and HttpResponseBase classes as parameters’ types instead of ASP.NET’s HttpRequest and HttpResponse classes. If you open a file named ConsumerService.aspx.cs in the SP project, you will see similar syntax as shown below:

C#:

// Create a SAML response from the HTTP request.
ComponentPro.Saml2.Response samlResponse = ComponentPro.Saml2.Response.Create(Request);

// Is it signed?
if (samlResponse.IsSigned())
{
    // Loaded the previously loaded certificate.
    X509Certificate2 x509Certificate = (X509Certificate2)Application[Global.CertKeyName];

    // Validate the SAML response with the certificate.
    if (!samlResponse.Validate(x509Certificate))
    {
        throw new ApplicationException("SAML response signature is not valid.");
    }
}

VB.NET:

' Create a SAML response from the HTTP request.
Dim samlResponse As ComponentPro.Saml2.Response = ComponentPro.Saml2.Response.Create(Request)

' Is it signed?
If samlResponse.IsSigned() Then
    ' Loaded the previously loaded certificate.
    Dim x509Certificate As X509Certificate2 = CType(Application([Global].CertKeyName), X509Certificate2)

    ' Validate the SAML response with the certificate.
    If (Not samlResponse.Validate(x509Certificate)) Then
        Throw New ApplicationException("SAML response signature is not valid.")
    End If
End If

Here are some screenshots of the examples:

Identity Provider MVC website:

Service Provider MVC website: