Search code examples
c#wcfwifsts-securitytokenservice

How do I cause SecurityTokenServiceConfiguration to load configuration information from the app.config?


I am creating an STS with the WIF framework included in .NET 4.5. I am self-hosting this STS (for now), using the WSTrustServiceHost class. In order to do that, I am doing the following:

var conf = new SecurityTokenServiceConfiguration("isser name here", true)
{
    DisableWsdl          = true,
    SecurityTokenService = typeof(MyTokenService),
};
var ct   = new WSTrustServiceContract(conf);
var host = new WSTrustServiceHost(ct);

host.Open();
// ...

As you can see, I'm passing in true to the loadConfig parameter of the SecurityTokenServiceConfiguration constructor, which, says the documentation:

true to load settings from the configuration file; otherwise false.

I have an identityConfiguration element in my configuration file, but it does not seem to be loaded. I can make changes to the configuration file, f.e. I can alter the securityTokenHandlers, and those changes are not reflected in the constructed SecurityTokenServiceConfiguration.

In my app.config file, I have the following:

<system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="sts_behavior">
                <serviceCredentials useIdentityConfiguration="true" identityConfiguration="the_issuer_id">
                    <serviceCertificate findValue="7A5D7EB05EC741E45BF4EDA7E574F58DC31EF290" x509FindType="FindByThumbprint" storeName="My" storeLocation="LocalMachine" />
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <ws2007HttpBinding>
            <binding name="sts_binding">
                <security mode="Message">
                    <message clientCredentialType="UserName" />
                </security>
            </binding>
        </ws2007HttpBinding>
    </bindings>
    <services>
        <service name="System.ServiceModel.Security.WSTrustServiceContract" behaviorConfiguration="sts_behavior">
            <endpoint address="http://my-machine:54512/tokens" binding="ws2007HttpBinding" contract="System.ServiceModel.Security.IWSTrust13SyncContract" bindingConfiguration="sts_binding" />
        </service>
    </services>
</system.serviceModel>

As one can see, the <serviceCredentials> element refers to the <identityConfiguration> element present in the config file, and if I change this name to not match that <identityConfiguration> element, an error is thrown when the service host is opened. This <identityConfiguration> element is still not used, however, as I can <clear/> the security token handlers, and a token handler is still used when a request comes in.

How can I configure and self-host a custom STS with a minimum of programmatic configuration?


Solution

  • After much exploration, I've discovered that one of the overloads of the SecurityTokenServiceConfiguration constructor allows one to specify the name of the <identityConfiguration> element from which the configuration is loaded:

    //
    // Summary:
    //     Initializes a new instance of the System.IdentityModel.Configuration.SecurityTokenServiceConfiguration
    //     class that has the specified issuer name and signing credentials. Settings
    //     are loaded from the specified named configuration.
    //
    // Parameters:
    //   issuerName:
    //     The issuer name. Sets the System.IdentityModel.Configuration.SecurityTokenServiceConfiguration.TokenIssuerName
    //     property.
    //
    //   signingCredentials:
    //     The signing credentials for the STS. Sets the System.IdentityModel.Configuration.SecurityTokenServiceConfiguration.SigningCredentials
    //     property.
    //
    //   serviceName:
    //     The name of the <identityConfiguration> element from which the configuration
    //     is to be loaded.
    public SecurityTokenServiceConfiguration(string issuerName, SigningCredentials signingCredentials, string serviceName);