How to sign SAML assertion (C#, .NET)?

3,825 views
Skip to first unread message

RAF

unread,
Sep 17, 2008, 4:02:55 PM9/17/08
to DotNetDevelopment, VB.NET, C# .NET, ADO.NET, ASP.NET, XML, XML Web Services,.NET Remoting
Hi all,

I’m working on a C# ASP.NET app designed to post a signed SAML
document contained in a form to an external server (for SSO); the SAML
should be signed by a x509 certificate. I’m able to create a SAML
assertion (from which I can extract the XML that I need), but I’m at a
loss as to how to sign it. This is the code (some generic values have
been substituted in places, but otherwise it is exactly what I am
running). Please advise!

Thanks very much,
RAF

// Create certificate from file. It must contain private key!
X509Certificate2 cert = new X509Certificate2("c:\\test.cer");

// The private key contained in the certificate will be used
to sign the token.
X509AsymmetricSecurityKey signingKey = new
X509AsymmetricSecurityKey(cert);

// Here we create some SAML assertion with ID and Issuer name.
SamlAssertion assertion = new SamlAssertion();
assertion.AssertionId = “saml_assertion_id”;
assertion.Issuer = "issuerval";

//Not before, not after conditions
assertion.Conditions = new SamlConditions(DateTime.Now,
DateTime.Now.AddMinutes(10));

//
// Create some SAML subject.
SamlSubject samlSubject = new SamlSubject();
samlSubject.Name = userID;
samlSubject.NameQualifier = userID;

samlSubject.ConfirmationMethods.Add("urn:oasis:names:tc:SAML:
1.0:cm:bearer");

//
// Create userName SAML attribute with few values.
SamlAttribute attrUser = new SamlAttribute();
attrUser.Name = "userName";
attrUser.Namespace = "TestSiteMapper attributes";
attrUser.AttributeValues.Add(id);

//
// Create userName SAML attribute with few values.
SamlAttribute attrCustID = new SamlAttribute();
attrCustID.Name = "custId";
attrCustID.Namespace = "TestSiteAttributeMapper attributes";
attrCustID.AttributeValues.Add("custID");

//
// Now create the SAML statement containing one attribute and
one subject.
SamlAttributeStatement samlAttributeStatement = new
SamlAttributeStatement();
samlAttributeStatement.Attributes.Add(attrUser);
samlAttributeStatement.Attributes.Add(attrCustID);
samlAttributeStatement.SamlSubject = samlSubject;

// Append the statement to the SAML assertion.
assertion.Statements.Add(samlAttributeStatement);

IPHostEntry ipEntry =
Dns.GetHostEntry(System.Environment.MachineName);
SamlAuthenticationStatement samlAuthenticationStatement =
new SamlAuthenticationStatement(samlSubject,
"urn:oasis:names:tc:SAML:1.0:am:password",
DateTime.Now, null, ipEntry.AddressList[0].ToString(),
null);

assertion.Statements.Add(samlAuthenticationStatement);

SecurityKeyIdentifier ski = new SecurityKeyIdentifier(new
X509ThumbprintKeyIdentifierClause(cert));

assertion.SigningCredentials = new
SigningCredentials(signingKey,

SecurityAlgorithms.RsaSha1Signature,

SecurityAlgorithms.Sha1Digest,
ski);
SecurityToken token = new SamlSecurityToken(assertion);

RAF

unread,
Sep 22, 2008, 12:15:46 PM9/22/08
to DotNetDevelopment, VB.NET, C# .NET, ADO.NET, ASP.NET, XML, XML Web Services,.NET Remoting
Hey,

Just in case anyone was interested, this is the solution I arrived at:

SignedXml sig = new SignedXml(xmlDoc);

RSACryptoServiceProvider Key = new RSACryptoServiceProvider();

// Add the key to the SignedXml xmlDocument.
sig.SigningKey = Key;

// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "";

// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new
XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);

// Add the reference to the SignedXml object.
sig.AddReference(reference);


// Add an RSAKeyValue KeyInfo (optional; helps recipient find
key to validate).
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert2));
sig.KeyInfo = keyInfo;

// Compute the signature.

sig.ComputeSignature();

// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = sig.GetXml();

Then you have to attach the xmlDigitalSignature to the xmlDocument
(there were specific rules for my app as to where this could happen,
so it's a little bit more complicated in my situation that it might be
in other apps -- but the idea is very simple: append, or insert before/
after a specific node).
Reply all
Reply to author
Forward
0 new messages