Skip to content

Dynamic issuer name registry direct from STS federation metadata with Thinktecture IdentityModel

February 22, 2013

In order for a RP to trust a token issued by an STS it must be configured with the public key (or public key thumbprint) from the STS’ metadata. These keys expire and thus periodically the RP must be updated. For a large number of RPs this is a non-trivial task. Therefore it is desirable to have an automated or dynamic mechanism for updating an RP with the set of signing keys used by a STS.

In order to always have the latest federation metadata from the STS, a MetadataBasedIssuerNameRegistry class was added to Thinktecture IdentityModel. It is configured with the issuer name desired to be used by the RP and the URL of the STS’s federation metadata endpoint and then loaded at runtime to discover the STS’ signing keys and those are used to build the WIF’s issuer name registry.

The MetadataBasedIssuerNameRegistry can be configured in web.config:

<system.identityModel>
  <identityConfiguration>
    <issuerNameRegistry
       type="Thinktecture.IdentityModel.Tokens.MetadataBasedIssuerNameRegistry,
             Thinktecture.IdentityModel">
      <trustedIssuerMetadata issuerName="sts"
                             metadataAddress="https://localhost/sts/FederationMetadata/2007-06/FederationMetadata.xml">
      </trustedIssuerMetadata>
    </issuerNameRegistry>

The <trustedIssuerMetadata> element has attributes for the issuer name and the URL for the federation metatadata.

The MetadataBasedIssuerNameRegistry can also be configured code from global.asax:

protected void Application_Start()
{
    FederatedAuthentication.FederationConfigurationCreated +=
        FederatedAuthentication_FederationConfigurationCreated;

    ...
}

void FederatedAuthentication_FederationConfigurationCreated(
    object sender, FederationConfigurationCreatedEventArgs e)
{
    var url = "https://localhost/sts/FederationMetadata/2007-06/FederationMetadata.xml";

    e.FederationConfiguration.IdentityConfiguration.IssuerNameRegistry =
        new MetadataBasedIssuerNameRegistry(new Uri(url), "sts");
}

The main downside with the MetadataBasedIssuerNameRegistry is that the metadata is loaded each time the RP application starts. It was then desired to provide a caching mechanism on top of the MetadataBasedIssuerNameRegistry, and thus the CachingMetadataBasedIssuerNameRegistry was also developed.

The CachingMetadataBasedIssuerNameRegistry inherits from MetadataBasedIssuerNameRegistry and simply provides caching logic on top of the dynamically loaded metadata. The cache is abstracted with an IMetadataCache interface so different implementations can be provided as needed.

The IMetadataCache definition is:

public interface IMetadataCache
{
    TimeSpan Age { get; }
    byte[] Load();
    void Save(byte[] data);
}

Given the semantics of the metadata there is only one item (as a byte[]) that needs to be cached. Its age is needed for repopulating the cache. For reference a file system based implementation is provided and is called FileBasedMetadataCache.

Configuring the CachingMetadataBasedIssuerNameRegistry can be done in web.config:

<issuerNameRegistry
     type="Thinktecture.IdentityModel.Tokens.CachingMetadataBasedIssuerNameRegistry,
           Thinktecture.IdentityModel">
  <trustedIssuerMetadata issuerName="sts"
                         metadataAddress="https://localhost/sts/FederationMetadata/2007-06/FederationMetadata.xml"></trustedIssuerMetadata>
  <metadataCache cacheDuration="30"
                 cacheType="Thinktecture.IdentityModel.Tokens.FileBasedMetadataCache,
                            Thinktecture.IdentityModel"
                  >
    <file path="c:\demos\cache.xml"></file>
  </metadataCache>
</issuerNameRegistry>

The <trustedIssuerMetadata> configuration is the same as before. The <metadataCache> element provides a cacheDuration attribute for the number of days to cache the metadata. There is also a cacheType attribute that indicates the class that implements the IMetadataCache interface. As displayed above, the FileBasedMetadataCache supports its own <file> configuration element to indicate the path to the file. The IIS worker process identity will require write privileges to this file.

Configuring the CachingMetadataBasedIssuerNameRegistry can be done in code in global.asax:

void FederatedAuthentication_FederationConfigurationCreated(
    object sender, FederationConfigurationCreatedEventArgs e)
{
    var url = "https://localhost/sts/FederationMetadata/2007-06/FederationMetadata.xml";
    var cache = new FileBasedMetadataCache(@"c:\demos\cache.xml");
    e.FederationConfiguration.IdentityConfiguration.IssuerNameRegistry =
        new CachingMetadataBasedIssuerNameRegistry(new Uri(url), "sts",
                                                   cache, 30);
}

The CachingMetadataBasedIssuerNameRegistry will load the metadata the first time from the STS but then cache it via the IMetadataCache for the duration specified. Each time the application then starts the cache should be used. The cache will also be pre-populated asynchronously if the age is less than half the remaining time of the cache duration. In other words, if the cache duration is 30 days and there is 15 or fewer days before expiration then the CachingMetadataBasedIssuerNameRegistry will attempt to contact the STS, acquire the latest metadata and update the cache.

One last aspect of the CachingMetadataBasedIssuerNameRegistry is that the cache is encrypted and signed via the MachineKey APIs in ASP.NET. This can be disabled by setting the optional protect flag to false in config or via the constructor argument.

No comments yet

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

%d bloggers like this: