Tag Archives: SAML Response

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:

 

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.