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(SamlAuthenticateContext.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:

 

Shibboleth Web Applications

After successfully installing the UltimateSaml for SAML v2.0 setup package you will see ten web sample projects in the folder WebFormsC# for C# and WebFormsVB.NET for VB.NET (By default UltimateSaml is installed in folder C:\ComponentPro with Vista, 2008 and above, C:\Program files\ComponentPro with XP, 2003, 2000). To run these web sample projects, open the solution file Saml2_Shibboleth_WebDemo.XXXX.sln for C# or Saml2_Shibboleth_WebDemoVB.XXXX.sln for VB.NET, and then select Saml2Shibboleth.IdentityProviderWebDemo or Saml2Shibboleth.ServiceProviderWebDemo.

These applications may also be used to demonstrate interoperability with Shibboleth. Shibboleth (http://shibboleth.internet2.edu) is an open source SSO software package using Java and C++ technologies. Installation and configuration of the Shibboleth software is beyond the scope of this document and is not required for this demonstration.

Identity Provider Web Application – Saml2Shibboleth.IdentityProviderWebDemo or Saml2Shibboleth.IdentityProviderWebDemoVB

This sample is configured to run at port 1423 (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 SP initiated single sign-on. The following steps will guide you how to run this sample project:

1. Login to the system with the user name iuser and a password of password.

ShiIP

2. You are now presented with the Identity Provider’s default page.

ShiIPLoggedIn

3. Click on the link to access the Service Provider site. You should be presented with the Service Provider’s default page.

ShiSPIP

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.

How to configure?

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

Service Provider Web Application – Saml2Shibboleth.ServiceProviderWebDemo or Saml2Shibboleth.ServiceProviderWebDemoVB

This sample is configured to run at port 1424 (you can easily change the port number in the project property page). The service provider web application, in conjunction with Identity Provider web application, demonstrates SP initiated single sign-on. You can directly login to the local system by entering credentials (suser/password) and clicking on the Login button (login to SP without Single Sign-On) or follow the steps below to run the application with Single Sign-On (In this scenario, the user is attempting to access a protected resource on the service provider and, rather than performing a local login at the service provider, SSO is initiated with a local login occurring at the identity provider and the asserted identity, passed to the service provider in a SAML assertion, is used to perform an automatic login at the service provider):

1. Click on the Login button under the text Login at the Identity Provider

ShiSP

2. You should then be presented with the Identity Provider’s login page as you will be logging in at the identity provider.

ShiIP

3. Login with user name iuser and a password of password. You should then be presented with the service provider’s default page.

ShiIPIP

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.

How to configure?

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

Single Sign On (SSO) Web Samples in Ultimate SAML Component

After successfully installing the UltimateSaml for SAML setup package you will see two SAML v1.1 web sample projects in the folder WebFormsC# for C# and WebFormsVB.NET for VB.NET (By default UltimateSaml is installed in folder C:\ComponentPro with Vista, 2008 and above, C:\Program files\ComponentPro with XP, 2003, 2000). To run these web sample projects, open the solution file Saml1_IdpInitiated_WebDemo.XXXX.sln for C# or Saml1_IdpInitiated_WebDemoVB.XXXX.sln for VB.NET.

Identity Provider Web Application (Saml1SsoIdentityProviderWebDemo or Saml1SsoIdentityProviderWebDemoVB)

This sample is configured to run at port 16471 (you can easily change the port number in the project property page). The identity provider web application demonstrates some basic operation of an identity provider. Firstly, you need to login to the system with the user name iuser and a password of password,

IdP

and choose a SAML Single Sign On method from a drop down list, and then click on a link to access the Service Provider site which runs at port 16475.

IdP

Once logged in at the identity provider, any access to the service provider is made through the identity provider’s inter-site transfer page (SamlRedirect.aspx) which handles both the Browser/POST and Browser/Artifact profile for the identity provider.

  • If using the browser/artifact profile, the identity provider‘s SAML responder page (SamlRequestProcess.aspx) handles SAML protocol requests from service providers. It uses the received artifact to look up the previously generated SAML assertion, creates a SAML protocol response containing this SAML assertion, and returns it to the service provider.

How to configure?

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

  • SamlArtifactUrlFormat: The target URL format of the service provider’s consumer service for Browser/Artifact SSO method.
  • SamlAssertionConsumerUrl: The target URL of the service provider’s consumer service for Browser/Post SSO method.

Service Provider Web Application (Saml1SsoServiceProviderWebDemo or Saml1SsoServiceProviderWebDemoVB)

This sample is configured to run at port 16475 (you can easily change the port number in the project property page). The service provider web application demonstrates some basic operation of a service provider.

  • If using browser/post, the assertion consumer page (SamlAssertionProcess.aspx) receives the form posted by the identity provider, reconstructs the SAML protocol response, retrieves the SAML assertion from the response, and uses the subject contained within the SAML assertion to perform an automatic login at the service provider. It then redirects to the target service provider page.
  • If using browser/artifact, the artifact receiver page (SamlArtifactProcess.aspx) receives the artifact from the identity provider. It then sends the identity provider a SAML protocol request containing the artifact, receives the SAML protocol response, retrieves the SAML assertion from the response, and uses the subject contained within the SAML assertion to perform an automatic login at the service provider. It then redirects to the target service provider page.

You can login to the local system with the user name suser and a password of password.

SP

How to configure?

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

  • SamlRequestHandlerUrl: The IdP’s SAML request handler url.

Verifying SAML XML Signatures with Saml1Demo

To verify a certificate that is being used in your application, you can run the Saml1Demo sample and click on the Verifying Signature tab to see whether the signature is valid. The following is the screen shot of the utility:

 SAML Verify

  • The Certificate File is a CER file containing the certificate to use to verify the signature. Only specify this parameter if the certificate is being loaded from a certificate file or store. If the certificate is included in the XML signature, then do not specify this parameter.
  • The SAML Protocol XML file is the file containing the SAML protocol response as XML.

Adding custom attributes to SAML Assertion

In many cases, you need to add custom attributes to a SAML response object and send it to an IdP or an SP. By accessing the attribute list using the Attributes property of the AttributeStatement class, you can easily pass your custom data to the IdP or SP. The following code illustrates how to add some custom attributes including Email, First Name, and Last Name of a user.

C#:

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);

VB.NET:

Dim attributeStatement As New AttributeStatement()
attributeStatement.Attributes.Add(New ComponentPro.Saml2.Attribute("email", SamlAttributeNameFormat.Basic, Nothing, "john@test.com"))
attributeStatement.Attributes.Add(New ComponentPro.Saml2.Attribute("FirstName", SamlAttributeNameFormat.Basic, Nothing, "John"))
attributeStatement.Attributes.Add(New ComponentPro.Saml2.Attribute("LastName", SamlAttributeNameFormat.Basic, Nothing, "Smith"))

' Insert a custom token key to the SAML response.
attributeStatement.Attributes.Add(New ComponentPro.Saml2.Attribute("CustomTokenForVerification", SamlAttributeNameFormat.Basic, Nothing, "YourEncryptedTokenHere"))

samlAssertion.Statements.Add(attributeStatement)

You can add this code to Service.aspx.cs file in Saml2IdpInitiated.IdentityProvider folder. The code after adding custom attributes should look like the following:

C#:

//#define ENCRYPTEDSAML

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(SamlAuthenticateContext.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.SendPostBindingForm(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();
        }
    }
}

Click here to download the Ultimate SAML SSO Component for ASP.NET.

Encrypting and Decrypting SAML Response XML

This topic illustrates how to encrypt a SAML Response XML on the Identity website and decrypt the XML on the Service Provider website.

Encrypting a SAML Response XML:

Instead of adding an unencrypted SAML Assertion to the SAML response with

// Add assertion to the SAML response object.
samlResponse.Assertions.Add(samlAssertion);

, we need to create an EncryptedAssertion object from the unencrypted Assertion object and add the EncryptedAssertion object to the SAML response object as shown in the code below:

// 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);

Decrypting the SAML Response XML:

In order to read the encrypted SAML response from the IdP on the Service Provider website, you need to decrypt it and convert to an Assertion object. The following code demonstrates how to do so:

if (samlResponse.GetEncryptedAssertions().Count > 0)
{
    EncryptedAssertion encryptedAssertion = samlResponse.GetEncryptedAssertions()[0];

    // Load the private key.
    // Consider caching the loaded key in production environment for better performance.
    X509Certificate2 decryptionKey = new X509Certificate2(Path.Combine(HttpRuntime.AppDomainAppPath, "EncryptionKey.pfx"), "password");

    // Decrypt the encrypted assertion.
    samlAssertion = encryptedAssertion.Decrypt(decryptionKey.PrivateKey, null);
}
else
{
    throw new ApplicationException("No encrypted assertions found in the SAML response");
}

How about decrypting encrypted attributes?

Very simple. All you need to do is to load a private key file for decrypting attributes and call the Decrypt method of the EncryptedAttribute class. The following code demonstrates how to do so.

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

// Access the first assertion object.
Assertion assertion = (Assertion)samlResponse.Assertions[0];

if (assertion.AttributeStatements[0].EncryptedAttributes.Count > 0)
{
    // Load the private key file.
    X509Certificate2 certificate = new X509Certificate2(privateCertificateFile, "password");

    // Loop through the encrypted attributes list.
    foreach (EncryptedAttribute encryptedAttribute in assertion.AttributeStatements[0].EncryptedAttributes)
    {
        // Get the encrypted key.
        EncryptedKey encryptedKey = encryptedAttribute.GetEncryptedKeyObjects()[0];

        // Decrypt the encrypted attribute.
        ComponentPro.Saml2.Attribute decryptedAttribute = encryptedAttribute.Decrypt(certificate.PrivateKey, encryptedKey, null);

        // ...
    }
}
else
{
    // Loop through the encrypted attributes list.
    foreach (ComponentPro.Saml2.Attribute attribute in assertion.AttributeStatements[0].Attributes)
    {
        // TO DO: Your code here.

        // ...
    }
}

Click here to download the Ultimate SAML SSO Component for ASP.NET.

Salesforce Web Applications

After successfully installing the UltimateSaml for SAML v2.0 setup package you will see ten web sample projects in the folder WebFormsC# for C# and WebFormsVB.NET for VB.NET (By default UltimateSaml is installed in folder C:\ComponentPro with Vista, 2008 and above, C:\Program files\ComponentPro with XP, 2003, 2000). This sample demonstrates Single Sign-on (SSO) with Salesforce in ComponentPro SAML Library. It acts as the Identity Provider while Salesforce is the Service Provider. To run this web sample project, open the solution file Saml2_Salesforce_WebDemo.XXXX.sln for C# or Saml2_Salesforce_WebDemoVB.XXXX.sln for VB.NET, and then select Saml2Salesforce.IdentifyProviderWebDemo.

Configuring the Salesforce Identify Provider Web Application

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

  • SalesforceUserId: The Salesforce account.
  • SalesforceLoginUrl: The Salesforce login URL. No need to change this value.
  • ServiceProviderUrl: The target URL of the service provider web application. No need to change this value.
  • CertificateIssuer: The certificate issuer name. This value must match the issuer name of the certificate submitted to Salesforce.
  • EntityId: Used to create an audience for a SAML response. No need to change this value.

Configuring Salesforce to work with your Identity Provider

To enable and configure single sign-on in Salesforce, you can follow the following steps:

  1. Login to Salesforce.
  2. Click on the Setup link, you should then be redirected to the Personal Setup page.
  3. Expand the Security Controls in the Adminsitration Setup menu, and select Single Sign-On Settings.
  4. Click on the Edit button.
    Ultimate SAML Salesforce Settings
  5. Choose SAML 2.0 as the SAML Version.
  6. Upload the Identity Provider Certificate if needed. If you wish to test the Identity Provider sample app, you will need to upload the certificate file named SP_X509Certificate_ForSalesforce.cer.
  7. You should select Assertion contains User’s salesforce.com username for the SAML User ID Type option, and User ID is in the NameIdentifier element of the Subject statement for the SAML User ID Location.
  8. Fill in the Identity Provider Certificate Name.
  9. Click on the Save button.

Testing the Identify Provider Web Application using UltimateSaml Library

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

  1. Click on the Login button.
  2. Click on the link “here”. You should then be presented with the Salesforce Account page.
    IdpLogin

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

If you need to setup Google SSO, please visit topic Setting up Google SSO to work with Ultimate SAML.

Click here to download the Ultimate SAML SSO Component for ASP.NET.