How to: Create a Supporting Credential

It is possible to have a custom security scheme that requires more than one credential. For example, a service may demand from the client not just a user name and password, but also a credential that proves the client is over the age of 18. The second credential is a supporting credential. This topic explains how to implement such credentials in an Windows Communication Foundation (WCF) client.

Note

The specification for supporting credentials is part of the WS-SecurityPolicy specification. For more information, see Web Services Security Specifications.

Supporting Tokens

In brief, when you use message security, a primary credential is always used to secure the message (for example, an X.509 certificate or a Kerberos ticket).

As defined by the specification, a security binding uses tokens to secure the message exchange. A token is a representation of a security credential.

The security binding uses a primary token identified in the security binding policy to create a signature. This signature is referred to as the message signature.

Additional tokens can be specified to augment the claims provided by the token associated with the message signature.

Endorsing, Signing, and Encrypting

A supporting credential results in a supporting token transmitted inside the message. The WS-SecurityPolicy specification defines four ways to attach a supporting token to the message, as described in the following table.

Purpose Description
Signed The supporting token is included in the security header and is signed by the message signature.
Endorsing An endorsing token signs the message signature.
Signed and Endorsing Signed, endorsing tokens sign the entire ds:Signature element produced from the message signature and are themselves signed by that message signature; that is, both tokens (the token used for the message signature and the signed endorsing token) sign each other.
Signed and Encrypting Signed, encrypted supporting tokens are signed supporting tokens that are also encrypted when they appear in the wsse:SecurityHeader.

Programming Supporting Credentials

To create a service that uses supporting tokens you must create a <customBinding>. (For more information, see How to: Create a Custom Binding Using the SecurityBindingElement.)

The first step when creating a custom binding is to create a security binding element, which can be one of three types:

All classes inherit from the SecurityBindingElement, which includes four relevant properties:

Scopes

Two scopes exist for supporting credentials:

  • Endpoint supporting tokens support all operations of an endpoint. That is, the credential that the supporting token represents can be used whenever any endpoint operations are invoked.

  • Operation supporting tokens support only a specific endpoint operation.

As indicated by the property names, supporting credentials can be either required or optional. That is, if the supporting credential is used if it is present, although it is not necessary, but the authentication will not fail if it is not present.

Procedures

To create a custom binding that includes supporting credentials

  1. Create a security binding element. The example below creates a SymmetricSecurityBindingElement with the UserNameForCertificate authentication mode. Use the CreateUserNameForCertificateBindingElement method.

  2. Add the supporting parameter to the collection of types returned by the appropriate property (Endorsing, Signed, SignedEncrypted, or SignedEndorsed). The types in the System.ServiceModel.Security.Tokens namespace include commonly used types, such as the X509SecurityTokenParameters.

Example

Description

The following example creates an instance of the SymmetricSecurityBindingElement and adds an instance of the KerberosSecurityTokenParameters class to the collection the Endorsing property returned.

Code

public static Binding CreateMultiFactorAuthenticationBinding()
{
    HttpTransportBindingElement httpTransport = new HttpTransportBindingElement();

    // The message security binding element will be configured to require 2 tokens:
    // 1) A user name/password encrypted with the service token.
    // 2) A client certificate used to sign the message.

    // Instantiate a binding element that will require the user name/password token
    // in the message (encrypted with the server certificate).
    SymmetricSecurityBindingElement messageSecurity = SecurityBindingElement.CreateUserNameForCertificateBindingElement();

    // Create supporting token parameters for the client X.509 certificate.
    X509SecurityTokenParameters clientX509SupportingTokenParameters = new X509SecurityTokenParameters();
    // Specify that the supporting token is passed in the message send by the client to the service.
    clientX509SupportingTokenParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
    // Turn off derived keys.
    clientX509SupportingTokenParameters.RequireDerivedKeys = false;
    // Augment the binding element to require the client's X.509 certificate as an
    // endorsing token in the message.
    messageSecurity.EndpointSupportingTokenParameters.Endorsing.Add(clientX509SupportingTokenParameters);

    // Create a CustomBinding based on the constructed security binding element.
    return new CustomBinding(messageSecurity, httpTransport);
}

See also