How to: Create a Federated Client

In Windows Communication Foundation (WCF), creating a client for a federated service consists of three main steps:

  1. Configure a <wsFederationHttpBinding> or similar custom binding. For more information about creating an appropriate binding, see How to: Create a WSFederationHttpBinding. Alternatively, run the ServiceModel Metadata Utility Tool (Svcutil.exe) against the metadata endpoint of the federated service to generate a configuration file for communicating with the federated service and one or more security token services.

  2. Set the properties of the IssuedTokenClientCredential that controls various aspects of a client's interaction with a security token service.

  3. Set the properties of the X509CertificateRecipientClientCredential, which allows certificates needed to communicate securely with given endpoints, such as security token services.

Note

A CryptographicException might be thrown when a client uses impersonated credentials, the WSFederationHttpBinding binding or a custom-issued token, and asymmetric keys. Asymmetric keys are used with the WSFederationHttpBinding binding and custom-issued tokens when the IssuedKeyType and KeyType properties, respectively, are set to AsymmetricKey. The CryptographicException is thrown when the client attempts to send a message and a user profile doesn’t exist for the identity that the client is impersonating. To mitigate this issue, log on to the client computer or call LoadUserProfile before sending the message.

This topic provides detailed information about these procedures. For more information about creating an appropriate binding, see How to: Create a WSFederationHttpBinding. For more information about how a federated service works, see Federation.

To generate and examine the configuration for a federated service

  1. Run the ServiceModel Metadata Utility Tool (Svcutil.exe) with the address of the metadata URL of the service as a command-line parameter.

  2. Open the generated configuration file in an appropriate editor.

  3. Examine the attributes and content of any generated <issuer> and <issuerMetadata> elements. These are located within the <security> elements for the <wsFederationHttpBinding> or custom bindings elements. Ensure that the addresses contain the expected domain names or other address information. It is important to check this information because the client authenticates to these addresses and may disclose information such as user name/password pairs. If the address is not the expected address, this could result in information disclosure to an unintended recipient.

  4. Examine any additional <issuedTokenParameters> elements inside the commented out <alternativeIssuedTokenParameters> element. When using the Svcutil.exe tool to generate configuration for a federated service, if the federated service or any intermediate security token services do not specify an issuer address, but rather specify a metadata address for a security token service that exposes multiple endpoints, the resulting configuration file refers to the first endpoint. Additional endpoints are in the configuration file as commented-out <alternativeIssuedTokenParameters> elements.

    Determine whether one of these <issuedTokenParameters> is preferable to the one already present in the configuration. For example, the client may prefer to authenticate to a security token service using a Windows CardSpace token rather than a user name/password pair.

    Note

    Where multiple security token services must be traversed before communicating with the service, it is possible for an intermediate security token service to direct the client to an incorrect security token service. Therefore, ensure that the endpoint for the security token service in the <issuedTokenParameters> is the expected security token service and not an unknown security token service.

To configure an IssuedTokenClientCredential in code

  1. Access the IssuedTokenClientCredential through the IssuedToken property of the ClientCredentials class (returned by the ClientCredentials property of the ClientBase<TChannel> class, or through the ChannelFactory class), as shown in the following example code.

    IssuedTokenClientCredential itcc = client.ClientCredentials.IssuedToken;
    
    Dim itcc As IssuedTokenClientCredential = client.ClientCredentials.IssuedToken
    
  2. If token caching is not required, set the CacheIssuedTokens property to false. The CacheIssuedTokens property controls whether such tokens from a security token service are cached. If this property is set to false, the client requests a new token from the security token service whenever it must re-authenticate itself to the federated service, regardless of whether a previous token is still valid. If this property is set to true, the client reuses an existing token whenever it must re-authenticate itself to the federated service (as long as the token has not expired). The default is true.

  3. If a time limit is required on cached tokens, set the MaxIssuedTokenCachingTime property to a TimeSpan value. The property specifies how long a token can be cached. After the specified time span has elapsed, the token is removed from the client cache. By default, tokens are cached indefinitely. The following example sets the time span to 10 minutes.

    itcc.MaxIssuedTokenCachingTime = new TimeSpan(0, 10, 0);
    
    itcc.MaxIssuedTokenCachingTime = New TimeSpan(0, 10, 0)
    
  4. Optional. Set the IssuedTokenRenewalThresholdPercentage to a percentage. The default is 60 (percent). The property specifies a percentage of the token's validity period. For example, if the issued token is valid for 10 hours and IssuedTokenRenewalThresholdPercentage is set to 80, then the token is renewed after eight hours. The following example sets the value to 80 percent.

    itcc.IssuedTokenRenewalThresholdPercentage = 80;
    
    itcc.IssuedTokenRenewalThresholdPercentage = 80
    

    The renewal interval determined by the token validity period and the IssuedTokenRenewalThresholdPercentage value is overridden by the MaxIssuedTokenCachingTime value in cases where the caching time is shorter than the renewal threshold time. For example, if the product of IssuedTokenRenewalThresholdPercentage and the token's duration is eight hours, and the MaxIssuedTokenCachingTime value is 10 minutes, the client contacts the security token service for an updated token every 10 minutes.

  5. If a key entropy mode other than CombinedEntropy is needed on a binding that does not use message security or transport security with message credentials (for example. the binding does not have a SecurityBindingElement), set the DefaultKeyEntropyMode property to an appropriate value. The entropy mode determines whether symmetric keys can be controlled using the DefaultKeyEntropyMode property. This default is CombinedEntropy, where both the client and the token issuer provide data that is combined to produce the actual key. Other values are ClientEntropy and ServerEntropy, which means the entire key is specified by the client or the server, respectively. The following example sets the property to use only the server data for the key.

    itcc.DefaultKeyEntropyMode = SecurityKeyEntropyMode.ServerEntropy;
    
    itcc.DefaultKeyEntropyMode = SecurityKeyEntropyMode.ServerEntropy
    

    Note

    If a SecurityBindingElement is present in a security token service or service binding, the DefaultKeyEntropyMode set on IssuedTokenClientCredential is overridden by the KeyEntropyMode property of the SecurityBindingElement.

  6. Configure any issuer-specific endpoint behaviors by adding them to the collection returned by the IssuerChannelBehaviors property.

    itcc.LocalIssuerChannelBehaviors.Add(myEndpointBehavior);
    
    itcc.LocalIssuerChannelBehaviors.Add(myEndpointBehavior)
    

To configure the IssuedTokenClientCredential in configuration

  1. Create an <issuedToken> element as a child of the <issuedToken> element in an endpoint behavior.

  2. If token caching is not required, set the cacheIssuedTokens attribute (of the <issuedToken> element) to false.

  3. If a time limit is required on cached tokens, set the maxIssuedTokenCachingTime attribute on the <issuedToken> element to an appropriate value. For example:
    <issuedToken maxIssuedTokenCachingTime='00:10:00' />

  4. If a value other than the default is preferred, set the issuedTokenRenewalThresholdPercentage attribute on the <issuedToken> element to an appropriate value, for example:

    <issuedToken issuedTokenRenewalThresholdPercentage = "80" />  
    
  5. If a key entropy mode other than CombinedEntropy is on a binding that does not use message security or transport security with message credentials (for example, the binding does not have a SecurityBindingElement), set the defaultKeyEntropyMode attribute on the <issuedToken> element to a either ServerEntropy or ClientEntropy as required.

    <issuedToken defaultKeyEntropyMode = "ServerEntropy" />  
    
  6. Optional. Configure any issuer-specific custom endpoint behavior by creating an <issuerChannelBehaviors> element as a child of the <issuedToken> element. For each behavior, create an <add> element as a child of the <issuerChannelBehaviors> element. Specify the issuer address of the behavior by setting the issuerAddress attribute on the <add> element. Specify the behavior itself by setting the behaviorConfiguration attribute on the <add> element.

    <issuerChannelBehaviors>  
    <add issuerAddress="http://fabrikam.org/sts" behaviorConfiguration="FabrikamSTS" />  
    </issuerChannelBehaviors>  
    

To configure an X509CertificateRecipientClientCredential in code

  1. Access the X509CertificateRecipientClientCredential through the ServiceCertificate property of the ClientCredentials property of the ClientBase<TChannel> class or the ChannelFactory property.

    X509CertificateRecipientClientCredential rcc =
        client.ClientCredentials.ServiceCertificate;
    
    Dim rcc As X509CertificateRecipientClientCredential = _
    client.ClientCredentials.ServiceCertificate
    
  2. If an X509Certificate2 instance is available for the certificate for a given endpoint, use the Add method of the collection returned by the ScopedCertificates property.

    rcc.ScopedCertificates.Add(new Uri("http://fabrikam.com/sts"), cert);
    
    rcc.ScopedCertificates.Add(New Uri("http://fabrikam.com/sts"), cert)
    
  3. If an X509Certificate2 instance is not available, use the SetScopedCertificate method of the X509CertificateRecipientClientCredential class as shown in the following example.

    public void snippet20(CalculatorClient client)
    {
        X509CertificateRecipientClientCredential rcc = client.ClientCredentials.ServiceCertificate;
        rcc.SetScopedCertificate(StoreLocation.CurrentUser,
                                 StoreName.TrustedPeople,
                                 X509FindType.FindBySubjectName,
                                 "FabrikamSTS",
                                 new Uri("http://fabrikam.com/sts"));
    }
    
    rcc.SetScopedCertificate(StoreLocation.CurrentUser, _
                StoreName.TrustedPeople, _
                X509FindType.FindBySubjectName, _
                "FabrikamSTS", _
                New Uri("http://fabrikam.com/sts"))
    

To configure an X509CertificateRecipientClientCredential in configuration

  1. Create a <scopedCertificates> element as a child of the <serviceCertificate> element that is itself a child of the <clientCredentials> element in an endpoint behavior.

  2. Create an <add> element as a child of the <scopedCertificates> element. Specify values for the storeLocation, storeName, x509FindType, and findValue attributes to refer to the appropriate certificate. Set the targetUri attribute to a value that provides the address of the endpoint that the certificate is to be used for, as shown in the following example.

    <scopedCertificates>  
     <add targetUri="http://fabrikam.com/sts"
          storeLocation="CurrentUser"  
          storeName="TrustedPeople"  
          x509FindType="FindBySubjectName"  
          findValue="FabrikamSTS" />  
    </scopedCertificates>  
    

Example

The following code sample configures an instance of the IssuedTokenClientCredential class in code.

// This method configures the IssuedToken property of the Credentials property of a proxy/channel factory
public static void ConfigureIssuedTokenClientCredentials(ChannelFactory cf, bool cacheTokens,
                                                          TimeSpan tokenCacheTime, int renewalPercentage,
                                                          SecurityKeyEntropyMode entropyMode
                                                          )
{
    if (cf == null)
    {
        throw new ArgumentNullException("cf");
    }
    // Set the CacheIssuedTokens property
    cf.Credentials.IssuedToken.CacheIssuedTokens = cacheTokens;

    // Set the MaxIssuedTokenCachingTime property
    cf.Credentials.IssuedToken.MaxIssuedTokenCachingTime = tokenCacheTime;

    // Set the IssuedTokenRenewalThresholdPercentage property
    cf.Credentials.IssuedToken.IssuedTokenRenewalThresholdPercentage = renewalPercentage;

    // Set the DefaultKeyEntropyMode property
    cf.Credentials.IssuedToken.DefaultKeyEntropyMode = entropyMode;
}

' This method configures the IssuedToken property of the Credentials property of a proxy/channel factory
Public Shared Sub ConfigureIssuedTokenClientCredentials(ByVal cf As ChannelFactory, _
                                                        ByVal cacheTokens As Boolean, _
                                                        ByVal tokenCacheTime As TimeSpan, _
                                                        ByVal renewalPercentage As Integer, _
                                                        ByVal entropyMode As SecurityKeyEntropyMode)
    If cf Is Nothing Then
        Throw New ArgumentNullException("ChannelFactory")
    End If
    ' Set the CacheIssuedTokens property
    With cf.Credentials.IssuedToken
        .CacheIssuedTokens = cacheTokens

        ' Set the MaxIssuedTokenCachingTime property
        .MaxIssuedTokenCachingTime = tokenCacheTime

        ' Set the IssuedTokenRenewalThresholdPercentage property
        .IssuedTokenRenewalThresholdPercentage = renewalPercentage

        ' Set the DefaultKeyEntropyMode property
        .DefaultKeyEntropyMode = entropyMode
    End With
End Sub

.NET Framework Security

To prevent possible information disclosure, clients that are running the Svcutil.exe tool to process metadata from federated endpoints should ensure that the resulting security token service addresses are what they expect. This is especially important when a security token service exposes multiple endpoints, because the Svcutil.exe tool generates the resulting configuration file to use the first such endpoint, which may not be the one the client should be using.

LocalIssuer Required

If clients are expected to always use a local issuer, note the following: the default output of Svcutil.exe results in the local issuer not being used if the second-to-last security token service in the chain specifies an issuer address or issuer metadata address.

For more information about setting the LocalIssuerAddress, LocalIssuerBinding, and LocalIssuerChannelBehaviors properties of the IssuedTokenClientCredential class, see How to: Configure a Local Issuer.

Scoped Certificates

If service certificates must be specified for communicating with any of the security token services, typically because certificate negotiation is not being used, they can be specified using the ScopedCertificates property of the X509CertificateRecipientClientCredential class. The SetDefaultCertificate method takes a Uri and an X509Certificate2 as parameters. The specified certificate is used when communicating with endpoints at the specified URI. Alternatively, you can use the SetScopedCertificate method to add a certificate to the collection returned by the ScopedCertificates property.

Note

The client idea of certificates that are scoped to a given URI applies only to applications that are making outbound calls to services that expose endpoints at those URIs. It does not apply to certificates that are used to sign issued tokens, such as those configured on the server in the collection returned by the KnownCertificates of the IssuedTokenServiceCredential class. For more information, see How to: Configure Credentials on a Federation Service.

See also