Geeks With Blogs

For the past several days I have been working on trying to build a WCF service which returns a list of assertions for a member.  Because this information will be handed off to a vendor, I have to meet their requirements for how the SAML will look and be encoded.  I am having all sorts of issues getting this to work! 

I know WCF and WIF together should help me.  I had the original service built in under three hours but the encoding did not match the vendor code's expectations.  Thus, I am hunting for a resolution.  Any help would be greatly appreciated.

So ... the service takes in a GUID which is used to call the database and return fields.  These are then used like so:

DataTable userData = GetDataForUser(userId);
List<Claim> claims = new List<Claim>()
    new Claim("ClientId", "NameOfClient")
foreach (DataRow row in userData.Rows)
    string memberId = row["MemberId"].ToString().Trim();
    string firstName = row["FirstName"].ToString().Trim();
    string lastName = row["LastName"].ToString().Trim();
    DateTime dob = Convert.ToDateTime(row["DateOfBirth"], CultureInfo.InvariantCulture);

    claims.Add(new Claim("MemberId", memberId));
    claims.Add(new Claim("FirstName", firstName));
    claims.Add(new Claim("LastName", lastName));
    claims.Add(new Claim("DOB", dob.ToString("MM/dd/yyyy")));

return claims;

Within the service, I then create a SecurityTokenDescriptor like this:

SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor();

The claims are added to the descriptor like so:

descriptor.Subject = new ClaimsIdentity(claims);

The descriptor is instructed to encrypt the token like this:

descriptor.EncryptingCredentials = GetEncryptingCredentials();

and the GetEncryptingCredentials() rotutine looks like this:

private EncryptedKeyEncryptingCredentials GetEncryptingCredentials()
    // Get the Encrypting Certificate
    X509Certificate2 encryptCert = CertificateHelper.FindSingleCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, X509FindType.FindBySubjectDistinguishedName, "<<certificate stuff here >>", true);

    EncryptedKeyEncryptingCredentials encryptingCreds = new EncryptedKeyEncryptingCredentials(encryptCert);

    return encryptingCreds;

All of this generates a token which, when written to a file gives me this:

  <EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
    <xenc:EncryptedData Id="_16584ace-9f3e-4352-9fc9-f6db8b2e925c" Type="" xmlns:xenc="">
      <xenc:EncryptionMethod Algorithm="" />
      <KeyInfo xmlns="">
        <e:EncryptedKey xmlns:e="">
          <e:EncryptionMethod Algorithm="">
            <DigestMethod Algorithm="" />
            <o:SecurityTokenReference xmlns:o="">
                  <X509IssuerName><!-- value --></X509IssuerName>
                  <X509SerialNumber><!-- value --></X509SerialNumber>
            <e:CipherValue><!-- value -->CipherValue>
      <xenc:CipherData><xenc:CipherValue><!-- value --></xenc:CipherValue>

Great, right?  Nope.  The vendor needs the <EncryptedData> section to have the following child node:

<EncryptionMethod Algorithm=""/>

And they need the <KeyInfo><EncryptedKey> section to show this:

<EncryptionMethod Algorithm=""/>

I have tried every combination I can think of within the GetEncryptingCredentials() routine.  Nothing has produced the desired results.  Anyone have a suggestion?  Don't be afraid to tell me to start all over.  That's all right.  I just need to get this to work.

Thanks in advance.

Posted on Monday, November 15, 2010 4:03 PM .Code | Back to top

Comments on this post: Please Help: Get WCF & WIF to generate specified SAML token pattern

# re: Please Help: Get WCF & WIF to generate specified SAML token pattern
Requesting Gravatar...
I have found an answer which is working right now. Still have to verify it works with the vendor, but the XML output is what I want.

I changed the GetEncryptingCredentials() routine to look like this:

private EncryptingCredentials GetEncryptingCredentials()
string keyWrapAlgorithm = SecurityAlgorithms.RsaV15KeyWrap;
string encryptionAlgorithm = SecurityAlgorithms.Aes128Encryption;
X509Certificate2 encryptCert = CertificateHelper.FindSingleCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, X509FindType.FindBySubjectDistinguishedName, << cert stuff>>, true);
EncryptingCredentials encryptingCredentials = new EncryptedKeyEncryptingCredentials(encryptCert, keyWrapAlgorithm, 256, encryptionAlgorithm);

return encryptingCredentials;

The key to it, I feel, is the change to using the EncryptingCredentials object and doing this through using an EncryptedKeyEncryptingCredentials object.

Like I said, the output is what I want. I will be testing with the vendor today and tomorrow.
Left by NEParis on Nov 16, 2010 2:18 PM

Your comment:
 (will show your gravatar)

Copyright © Erik France | Powered by: