Creating of SAML token

Damir Dobric Posts

Next talks:

 

Damir@Phone    

Follow me on Twitter: #ddobric



 

 

Archives

Security Assertion Markup Language well known as SAML is an XML standard for exchanging authentication and authorization data between security domains, that is, between an identity provider and a service provider. SAML is a product of the OASIS Security Services Technical Committee.

By implementing of web service security in interoperable application, you will be almost always required to deal with SAML token. Depending on what your are going to do, there are several helpful scenarios. Most important scenarios are:

  1. Create the new (signed) token
  2. Obtain the token from STS (Security Token Service) and do verification
  3. Persist the (unchanged) token (HDD or memory)
  4. Send the (unchanged) token to some provider (i.e.: WCF service)

Following example shows how to create the SAML token by using of WCF.

private static void Main(string[] args)
{
  SamlAssertion assertion = createSamlAssertion();
  SamlSecurityToken samlToken = new SamlSecurityToken(assertion);
}

/// <summary>
/// Creates some Test SAML assertion
/// </summary>
/// <returns></returns>
private static SamlAssertion createSamlAssertion()
{
  // Here we create some SAML assertion with ID and Issuer name.
  SamlAssertion assertion = new SamlAssertion();
  assertion.AssertionId = "DaenetSamlTest";
  assertion.Issuer = "damir";

  //
  // Create some SAML subject.
  SamlSubject samlSubject = new SamlSubject();
  samlSubject.Name = "My Subject";

  //
  // Create one SAML attribute with few values.
  SamlAttribute attr = new SamlAttribute();
    attr.Namespace = http://daenet.eu/saml;
    attr.AttributeValues.Add("Some Value 1");
  attr.AttributeValues.Add("Some Value 2");

  attr.Name = "My ATTR Value";

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

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

However, the SAML token makes a sense if it is digitally signed. Following code snippet shows how to sign the SAML token by using of the X509 certificate, which contains the private key:

/// <summary>
/// Creates some signed Test SAML assertion.
/// </summary>
/// <returns></returns>
private static SamlAssertion createSamlAssertion()
{
  //
  // Create certificate from file. It must contain private key!
  X509Certificate2 cert = new X509Certificate2("filename.cert");

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

  //
  // Signing credentials are consisted
  // of private key in the certificate (see above),
  // the signature algorithm, security algortihm and key identifier.
  assertion.SigningCredentials =
  new SigningCredentials(signingKey, SecurityAlgorithms.RsaSha1Signature,    
  SecurityAlgorithms
.Sha1Digest,
  new SecurityKeyIdentifier(new X509ThumbprintKeyIdentifierClause(cert)));

  // Finally create the SamlSecurityToken from the assertion
  SamlSecurityToken samlToken = new SamlSecurityToken(assertion);

  // Create a SecurityTokenSerializer that
  // will be used to serialize the SamlSecurityToken 
  WSSecurityTokenSerializer ser = new WSSecurityTokenSerializer(); 
  using (XmlWriter xWriter = XmlWriter.Create("saml.xml")) 
  {
    ser.WriteToken(xWriter, samlToken);
  }
}


In this example WSSecurityTokenSerializer is used to serialize the SAML token with the provided certificate. The token written in the file "saml.xml" by using of the XmlWriter .


Posted Feb 22 2007, 07:01 PM by Damir Dobric
Filed under:

Comments

Damir Dobric Posts wrote Verification of SAML token
on 02-22-2007 19:42

Security Assertion Markup Language well known as SAML is an XML standard for exchanging authentication

fan wrote re: Creating of SAML token
on 05-13-2009 5:19

The SAML token makes a sense if it is digitally signed?

Is it nessary?I think it just need encrypted.right ?

fan wrote re: Creating of SAML token
on 05-13-2009 18:09

hi, I.m studing the saml in the IDM interoperation, and have some questions, can you tell me your email?so that i can communicate with you in detail. thank you?

fan wrote re: Creating of SAML token
on 05-14-2009 3:42

i think you are bussy. when i run the progrom.

X509AsymmetricSecurityKey signingKey = new X509AsymmetricSecurityKey(cert);

throw out a excepion " can.t find the private key" . and you know the .cert file is genetated by makecert.exe. why?

Damir Dobric wrote re: Creating of SAML token
on 05-14-2009 17:47

It depends how you create self signed certificate. Here is the example how to create self-signed cerificate with exportable private key:

makecert.exe -sr LocalMachine -ss My -n CN=localhost -sky exchange -sk -pe

fan wrote re: Creating of SAML token
on 05-15-2009 11:32

thank you for your reply. i m sorry to trouble you again. i m a beginner in saml. i  generate the certi using your method, but when i export the certi from MMC which says the private key can't be exported. i have tried other ways, for exaple, .snk file, but according your code, only .cert or .cer file be accepted. i' d like to your reply. thanks.

Damir Dobric wrote re: Creating of SAML token
on 05-15-2009 15:38

You cannot export private key by MMC if created this way. But, you don't have to do it at all. new X509AsymmetricSecurityKey(cert) will do it for you.

fan wrote re: Creating of SAML token
on 05-18-2009 5:04

acccording to X509Certificate2 cert = new X509Certificate2("filename.cert"); if i don't export it, where do  "filename.cert"  store? , and what is the name of the "filename" and its full path?

if i use "makecert.exe -sr LocalMachine -ss My -n CN=localhost -sky exchange -sk -pe" to generate the certi, the cert is stored in "My" storege field, how can i get it? or what's the concrete value of the "filename.cert"? thank you!

Damir Dobric wrote re: Creating of SAML token
on 05-18-2009 19:07

Here is one method which retrieves a certificate from the proper store without of using of certificate file:

  /// <summary>

           /// This helper method retrieves the specified certificate from the TrustePeople store at specified location.

           /// </summary>

           /// <param name="storeName">The name of the store.</param>

           /// <param name="storeLocation">The location of the store.</param>

           /// <param name="x509FindType">The find type.</param>

           /// <param name="findValue">The value to search.</param>

           /// <returns>The target certificate if found. Otherwise null value.</returns>

           public static X509Certificate2 GetCertificate(

               StoreLocation storeLocation,

               StoreName storeName,

               CertificateSearchValue x509FindType,

               string findValue)

           {

               X509Store store = new X509Store(storeName, storeLocation);

               store.Open(OpenFlags.ReadOnly);

               foreach (X509Certificate2 cert in store.Certificates)

               {

                   if (x509FindType == CertificateSearchValue.SearchBySubjectName)

                   {

                       if (cert.Subject == findValue)

                       {

                           return cert;

                       }

                   }

                   else if (x509FindType == CertificateSearchValue.SearchByThumbprint)

                   {

                       if (String.Compare(cert.Thumbprint.ToString(), findValue.ToString(), true, CultureInfo.InvariantCulture) == 0)

                       {

                           return cert;

                       }

                   }

               }

               return null;

           }

fan wrote re: Creating of SAML token
on 05-20-2009 15:00

hi, in your code the "CertificateSearchValue x509FindType", i think should be "x509FindType CertificateSearchValue".

but there is a exception that "The SamlAssertion could not be serialized to XML. Please see inner exception for details."  when i debuy it at the code " ser.WriteToken(xWriter, samlToken); ". why? my platform are: vs2005,.net 3.5. I'm hoping  for your reply, thank you.

fan wrote re: Creating of SAML token
on 05-22-2009 5:17

hi, when i debuy it, it stopped at "ser.WriteToken(xWriter, samlToken); ", throw out a exception"SamlAssertion can't be serialized". why?

tak wrote re: Creating of SAML token
on 06-18-2009 12:51

Where can I find library for this code please?

steven wrote re: Creating of SAML token
on 08-14-2009 5:21

could you give me the library of your code?

how can I use it ?

sli@ttg.cc

Dharma wrote re: Creating of SAML token
on 10-13-2009 12:38

Hi,

 After implementing your code i'm getting the following exception. WHat could be the problem?

System.Xml.XmlException was unhandled by user code

 Message="There was an error serializing the security token. Please see the inner exception for more details."

 Source="System.ServiceModel"

 LineNumber=0

 LinePosition=0

 StackTrace:

      at System.ServiceModel.Security.WSSecurityTokenSerializer.WriteTokenCore(XmlWriter writer, SecurityToken token)

      at System.IdentityModel.Selectors.SecurityTokenSerializer.WriteToken(XmlWriter writer, SecurityToken token)

      at SAMLPerfMan.login.createSamlAssertion() in C:\Documents and Settings\DJNA\My Documents\Visual Studio 2008\Projects\SAMLPerfMan\SAMLPerfMan\login.aspx.cs:line 88

      at SAMLPerfMan.login.Page_Load(Object sender, EventArgs e) in C:\Documents and Settings\DJNA\My Documents\Visual Studio 2008\Projects\SAMLPerfMan\SAMLPerfMan\login.aspx.cs:line 26

      at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)

      at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)

      at System.Web.UI.Control.OnLoad(EventArgs e)

      at System.Web.UI.Control.LoadRecursive()

      at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

 InnerException: System.InvalidOperationException

      Message="The SamlAssertion could not be serialized to XML. Please see inner exception for details."

      Source="System.IdentityModel"

      StackTrace:

           at System.IdentityModel.Tokens.SamlAssertion.WriteXml(XmlDictionaryWriter writer, SamlSerializer samlSerializer, SecurityTokenSerializer keyInfoSerializer)

           at System.IdentityModel.Tokens.SamlAssertion.WriteTo(XmlWriter writer, SamlSerializer samlSerializer, SecurityTokenSerializer keyInfoSerializer)

           at System.IdentityModel.Tokens.SamlSerializer.WriteToken(SamlSecurityToken token, XmlWriter writer, SecurityTokenSerializer keyInfoSerializer)

           at System.ServiceModel.Security.WSSecurityJan2004.SamlTokenEntry.WriteTokenCore(XmlDictionaryWriter writer, SecurityToken token)

           at System.ServiceModel.Security.WSSecurityTokenSerializer.WriteTokenCore(XmlWriter writer, SecurityToken token)

      InnerException: System.NotSupportedException

           Message="The private key is not present in the X.509 certificate."

           Source="System.IdentityModel"

           StackTrace:

                at System.IdentityModel.Tokens.X509AsymmetricSecurityKey.GetSignatureFormatter(String algorithm)

                at System.IdentityModel.SignedXml.ComputeSignature(SecurityKey signingKey)

                at System.IdentityModel.Tokens.SamlAssertion.System.IdentityModel.ICanonicalWriterEndRootElementCallback.OnEndOfRootElement(XmlDictionaryWriter dictionaryWriter)

                at System.IdentityModel.SamlDelegatingWriter.OnEndOfRootElement()

                at System.IdentityModel.SamlDelegatingWriter.WriteEndElement()

                at System.IdentityModel.Tokens.SamlAssertion.WriteXml(XmlDictionaryWriter writer, SamlSerializer samlSerializer, SecurityTokenSerializer keyInfoSerializer)

           InnerException:

Dharma wrote re: Creating of SAML token
on 10-14-2009 13:20

Hi,

  I tried implementing the above example (second example) it is giving an inner exception "The private key is not present in the X.509 certificate." and more over in the statement  SamlAssertion assertion = createSamlAssertion(); are you calling the same method?? Also there is no return statement in the method. PLease explain me how to implement your code.

Danila Polevshikov wrote re: Creating of SAML token
on 02-27-2013 9:37

I got expection while validating manually created SAML token:

The Saml2SecurityToken cannot be validated because the IssuerToken property is not set. Unsigned SAML2:Assertions cannot be validated.

Reason was that new SamlSecurityToken(assertion) is not sign token, and i have to use Saml2SecurityToken(Saml2Assertion assertion, ReadOnlyCollection<SecurityKey> keys, SecurityToken issuerToken) instead.

developers.de is a .Net Community Blog powered by daenet GmbH.