How to: Create a WSFederationHttpBinding

In Windows Communication Foundation (WCF), the WSFederationHttpBinding class (<wsFederationHttpBinding> in configuration) provides a mechanism for exposing a federated service. That is, a service that requires clients to authenticate using a security token issued by a security token service. This topic shows how to set up a WSFederationHttpBinding in both code and configuration. Once the binding is created, you can set up an endpoint to use that binding.

The basic steps are outlined as follows:

  1. Select a security mode. The WSFederationHttpBinding supports Message, which provides end-to-end security at the message level, even across multiple hops, and TransportWithMessageCredential, which provides better performance in cases where the client and the service can make a direct connection over HTTPS.

    Note

    The WSFederationHttpBinding also supports None as a security mode. This mode is not secure and is provided for debugging purposes only. If a service endpoint is deployed with a WSFederationHttpBinding with its security mode set to None, the resulting client binding (generated by the ServiceModel Metadata Utility Tool (Svcutil.exe)) is a WSHttpBinding with a security mode of None.

    Unlike other system-provided bindings, it is not necessary to select a client credential type when using the WSFederationHttpBinding. This is because the client credential type is always an issued token. WCF acquires a token from a specified issuer and presents that token to the service to authenticate the client.

  2. On federated clients, set the IssuerAddress property to the URL of the security token service. Set the IssuerBinding to the binding to use to communicate with the security token service.

  3. Optional. Set the IssuedTokenType property to the Uniform Resource Identifier (URI) of a token type. On federated services, specify the token type that the service expects. On federated clients, specify the token type the client requests from the security token service.

    If no token type is specified, clients generate WS-Trust Request Security Tokens (RSTs) without a token type URI, and services expect client authentication using a Security Assertions Markup Language (SAML) 1.1 token by default.

    The URI for a SAML 1.1 token is http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1.

  4. Optional. On federated services, set the IssuerMetadataAddress property to the metadata URL of a security token service. The metadata endpoint enables clients of the service to select an appropriate binding/endpoint pair, if the service is configured to publish metadata. For more information about publishing metadata, see Publishing Metadata.

You can also set other properties, including the type of key used as a proof key in the issued token, the algorithm suite to use between the client and the service, whether to negotiate or explicitly specify the service credential, any specific claims the service expects the issued token to contain, and any additional XML elements that must be added to the request the client sends to the security token service.

Note

The NegotiateServiceCredential property is only relevant when the SecurityMode is set to Message. If SecurityMode is set to TransportWithMessageCredential, then the NegotiateServiceCredential property is ignored.

To configure a WSFederationHttpBinding in code

  1. Create an instance of the WSFederationHttpBinding.

  2. Set the Mode property to WSFederationHttpSecurityMode or Message as required. If an algorithm suite other than Basic256 is required, set the AlgorithmSuite property to a value taken from SecurityAlgorithmSuite.

  3. Set the NegotiateServiceCredential property as appropriate.

  4. Set the IssuedKeyType property to SecurityKeyTypeSymmetricKey or .AsymmetricKey as required.

  5. Set the IssuedTokenType property to the appropriate value. If no value is set, WCF defaults to http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1, which indicates SAML 1.1 tokens.

  6. Required on the client if no local issuer is specified; optional on the service. Create an EndpointAddress that contains the address and identity information of the security token service and assign the EndpointAddress instance to the IssuerAddress property.

  7. Required on the client if no local issuer is specified; not used on the service. Create a Binding for the SecurityTokenService and assign the Binding instance to the IssuerBinding property.

  8. Not used on the client; optional on the service. Create an EndpointAddress instance for the metadata of the security token service and assign it to the IssuerMetadataAddress property.

  9. Optional on both the client and the service. Create and add one or more ClaimTypeRequirement instances to the collection returned by the ClaimTypeRequirements property.

  10. Optional on both the client and the service. Create and add one or more XmlElement instances to the collection returned by the TokenRequestParameters property.

To create a federated endpoint in configuration

  1. Create a <wsFederationHttpBinding> as a child of the <bindings> element in the application configuration file.

  2. Create a <binding> element as a child of <wsFederationHttpBinding> and set the name attribute to an appropriate value.

  3. Create a <security> element as a child of the <binding> element.

  4. Set the mode attribute on the <security> element to a value of Message or TransportWithMessageCredential, as required.

  5. Create a <message> element as a child of the <security> element.

  6. Optional. Set the algorithmSuite attribute on the <message> element with an appropriate value. The default is Basic256.

  7. Optional. If an asymmetric proof key is required, set the issuedKeyType attribute of the <message> element to AsymmetricKey. The default is SymmetricKey.

  8. Optional. Set the issuedTokenType attribute on the <message> element.

  9. Required on the client if no local issuer is specified; optional on the service. Create an <issuer> element as a child of the <message> element.

  10. Set the address attribute to the <issuer> element and specify the address at which the security token service accepts token requests.

  11. Optional. Add an <identity> child element and specify the identity of the security token service

  12. For more information, see Service Identity and Authentication.

  13. Required on the client if no local issuer is specified; not used on the service. Create a <binding> element in the bindings section that can be used to communicate with the security token service. For more information about creating a binding, see How to: Specify a Service Binding in Configuration.

  14. Specify the binding created in the previous step by setting the binding and bindingConfiguration attributes of the <issuer> element.

  15. Not used on the client; optional on the service. Create an <issuerMetadata> element as a child of the <message> element. Then, in an address attribute on the <issuerMetadata> element, specify the address at which the security token service is to publish its metadata. Optionally, add an <identity> child element and specify the identity of the security token service.

  16. Optional on both the client and the service. Add a <claimTypeRequirements> element as a child of the <message> element. Specify required and optional claims that the service relies on by adding <add> elements to the <claimTypeRequirements> element and specifying the claim type with the claimType attribute. Specify whether a given claim is required or optional by setting the isOptional attribute.

Example

The following code sample shows code for setting up a WSFederationHttpBinding imperatively.

// This method creates a WSFederationHttpBinding.
public static WSFederationHttpBinding
    CreateWSFederationHttpBinding(bool isClient)
{
  // Create an instance of the WSFederationHttpBinding.
  WSFederationHttpBinding b = new WSFederationHttpBinding();

  // Set the security mode to Message.
  b.Security.Mode = WSFederationHttpSecurityMode.Message;

  // Set the Algorithm Suite to Basic256Rsa15.
  b.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Basic256Rsa15;

  // Set NegotiateServiceCredential to true.
  b.Security.Message.NegotiateServiceCredential = true;

  // Set IssuedKeyType to Symmetric.
  b.Security.Message.IssuedKeyType = SecurityKeyType.SymmetricKey;

  // Set IssuedTokenType to SAML 1.1
  b.Security.Message.IssuedTokenType =
      "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#samlv1.1";
    
  // Extract the STS certificate from the certificate store.
  X509Store store = new X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser);
  store.Open(OpenFlags.ReadOnly);
  X509Certificate2Collection certs = store.Certificates.Find(
      X509FindType.FindByThumbprint, "0000000000000000000000000000000000000000", false);
  store.Close();

  // Create an EndpointIdentity from the STS certificate.
  EndpointIdentity identity = EndpointIdentity.CreateX509CertificateIdentity ( certs[0] );

  // Set the IssuerAddress using the address of the STS and the previously created
  // EndpointIdentity.
  b.Security.Message.IssuerAddress =
      new EndpointAddress(new Uri("http://localhost:8000/sts/x509"), identity);

  // Set the IssuerBinding to a WSHttpBinding loaded from configuration.
  // The IssuerBinding is only used on federated clients.
  if (isClient)
  {
      b.Security.Message.IssuerBinding = new WSHttpBinding("Issuer");
  }

  // Set the IssuerMetadataAddress using the metadata address of the STS and the
  // previously created EndpointIdentity. The IssuerMetadataAddress is only used
  // on federated services.
  else
  {
      b.Security.Message.IssuerMetadataAddress =
          new EndpointAddress(new Uri("http://localhost:8001/sts/mex"), identity);
  }
  // Create a ClaimTypeRequirement.
  ClaimTypeRequirement ctr = new ClaimTypeRequirement
      ("http://example.org/claim/c1", false);

  // Add the ClaimTypeRequirement to ClaimTypeRequirements
  b.Security.Message.ClaimTypeRequirements.Add(ctr);

  // Return the created binding
  return b;
}
' This method creates a WSFederationHttpBinding.
Public Shared Function CreateWSFederationHttpBinding(ByVal isClient As Boolean) As WSFederationHttpBinding
    ' Create an instance of the WSFederationHttpBinding.
    Dim b As New WSFederationHttpBinding()
    With b.Security
        ' Set the security mode to Message.
        .Mode = WSFederationHttpSecurityMode.Message

        With .Message
            ' Set the Algorithm Suite to Basic256Rsa15.
            .AlgorithmSuite = SecurityAlgorithmSuite.Basic256Rsa15

            ' Set NegotiateServiceCredential to true.
            .NegotiateServiceCredential = True

            ' Set IssuedKeyType to Symmetric.
            .IssuedKeyType = SecurityKeyType.SymmetricKey

            ' Set IssuedTokenType to SAML 1.1
            .IssuedTokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#samlv1.1"
        End With
    End With

    ' Extract the STS certificate from the certificate store.
    Dim store As New X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser)
    store.Open(OpenFlags.ReadOnly)
    Dim certs = store.Certificates.Find(X509FindType.FindByThumbprint, _
                                        "0000000000000000000000000000000000000000", _
                                        False)
    store.Close()

    ' Create an EndpointIdentity from the STS certificate.
    Dim identity = EndpointIdentity.CreateX509CertificateIdentity(certs(0))

    ' Set the IssuerAddress using the address of the STS and the previously created 
    ' EndpointIdentity.
    With b.Security.Message
        .IssuerAddress = New EndpointAddress(New Uri("http://localhost:8000/sts/x509"), _
                                                                           identity)

        ' Set the IssuerBinding to a WSHttpBinding loaded from configuration. 
        ' The IssuerBinding is only used on federated clients.
        If isClient Then
            .IssuerBinding = New WSHttpBinding("Issuer")

            ' Set the IssuerMetadataAddress using the metadata address of the STS and the
            ' previously created EndpointIdentity. The IssuerMetadataAddress is only used 
            ' on federated services.
        Else
            .IssuerMetadataAddress = New EndpointAddress(New Uri("http://localhost:8001/sts/mex"), _
                                                                           identity)
        End If
        ' Create a ClaimTypeRequirement.
        Dim ctr As New ClaimTypeRequirement("http://example.org/claim/c1", _
                                            False)

        ' Add the ClaimTypeRequirement to ClaimTypeRequirements
        .ClaimTypeRequirements.Add(ctr)
    End With

    ' Return the created binding
    Return b
End Function

See also