How to send Authentication Request using the HttpResponse or HttpResponseBase object

We recently received a 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?" To answer those questions, we have three sections as follows:

How to create an authentication statement

In order to create an authentication statement, you need to create a SAML Response and then add an Assertion to it. An authentication statement is created using the AuthnStatement class. You can add custom attributes like email, first name, and last name to that object. That statement will then be added to the Statements property of the Assertion object. An example of how an AuthnStatement object is created is shown below:

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

You will notice that the GetAbsoluteUrl method is not defined in that code. That method returns an absolute URL of a given relative URL:

private string GetAbsoluteUrl(string relativeUrl)
{
	Uri u = new Uri(Request.Url, ResolveUrl(relativeUrl));
	return u.ToString();
}

If your SAML Response needs to be signed, you can load a certificate and sign it with the Sign method. Use the SendHttpPost to send that response to the desired target page (i.e. a Service Provider URL).

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

What is the parameter Response passed to the SendHttpPost method?

In the SendHttpPost method, you can pass either an HttpResponse or HttpResponseBase object depending whether you are using the library in an ASP.NET or MVC application. You can also specify a stream object instead as show in the first section.

What is the relay state?

It's a optional token that may be sent along with a Response message. It depends on how you want to use it. An example of its usage is to store a URL a Service Provider should redirect back when an SSO operation completes. It may also be a session ID which will be parsed to retrieve the corresponding information on the Identity Provider.

45-Day Money Back Guarantee

We will refund your full money in 45 days
if you are not satisfied with our products

Buy Now