Generating Federation Metadata using WIF APIs

Just like all the Service Oriented approaches, metadata is the key, for example, with web services, you just have to build the service (using ASMX file or WCF) it will generate the WSDL file for your service automatically, so the client code can easily consume. We expect the same thing with WIF, unfortunately, we cannot just build a STS and then somehow it exposes the federation metadata for that.

Most of the samples in WIF SDK and the Programming WIF book are showing you how to generate the metadata from a Visual Studio template. But there is almost no documentation on how to create the federation metadata manually (or dynamically), especially when you build a custom STS using MVC (hopefully we will have the template for MVC soon, but still not solving the dynamic issue).

WIF itself does provide APIs for this task, below are some very simple codes (I copy most of them from http://netpl.blogspot.com/2011/08/quest-for-customizing-adfs-sign-in-web.html). I just tried to put thing together and see how to use the WIF metadata API. For a more complete sample, please see the link above.


const string _endpoint = "http://yoursts.com";

static void Main(string[] args)
{
 string endpointId = _endpoint;
 EntityDescriptor entityDescriptor = new EntityDescriptor(
 new EntityId(endpointId));

 // Signature, I created a certificate using portecle and installed
 // it under TrustedPeople/CurrentUser
 X509Certificate2 cert =
 CertificateUtil.GetCertificate(
 StoreName.TrustedPeople, StoreLocation.CurrentUser, "CN=HoaSTSCert, C=US");

 entityDescriptor.SigningCredentials = new X509SigningCredentials(cert);

 SecurityTokenServiceDescriptor roleDescriptor = new SecurityTokenServiceDescriptor();

 // required protocols supported
 roleDescriptor.ProtocolsSupported.Add(new Uri(WSFederationMetadataConstants.Namespace));
 roleDescriptor.Contacts.Add(new ContactPerson(ContactType.Administrative));

 // This section is for key descriptor
 SecurityKeyIdentifierClause clause = new X509RawDataKeyIdentifierClause(cert);
 SecurityKeyIdentifier ski = new SecurityKeyIdentifier(clause);
 KeyDescriptor signingKey = new KeyDescriptor(ski);
 signingKey.Use = KeyType.Signing;
 roleDescriptor.Keys.Add(signingKey);

// This section is for endpoint
 string activeSTSUrl = _endpoint;
 EndpointAddress endpointAddress = new EndpointAddress(
 new Uri(activeSTSUrl),
 null,
 null,
 (XmlDictionaryReader)null,
 null);

 // Active endpoint
 roleDescriptor.SecurityTokenServiceEndpoints.Add(endpointAddress);
 // Passive endpoint
 roleDescriptor.PassiveRequestorEndpoints.Add(endpointAddress);

 roleDescriptor.ClaimTypesOffered.Add(new DisplayClaim(ClaimTypes.Role));
 roleDescriptor.ClaimTypesOffered.Add(new DisplayClaim(ClaimTypes.Name));

 entityDescriptor.RoleDescriptors.Add(roleDescriptor);

 // Serialize process...
 MetadataSerializer serializer = new MetadataSerializer();

 //MemoryStream stream = new MemoryStream();
 string fileName = @"FederationMetadata.xml";
 XmlWriter writer = XmlWriter.Create(fileName);
 XmlWriterSettings settings = new XmlWriterSettings();
 settings.Indent = true;

 serializer.WriteMetadata(writer, entityDescriptor);

 writer.Flush();

 Console.WriteLine("done...");
 Console.WriteLine(string.Format("Output: {0}",
 Path.Combine(Environment.CurrentDirectory, fileName)));
}

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s