Partilhar via


Service Identity and Authentication

A service's endpoint identity is a value generated from the service Web Services Description Language (WSDL). This value, propagated to any client, is used to authenticate the service. After the client initiates a communication to an endpoint and the service authenticates itself to the client, the client compares the endpoint identity value with the actual value the endpoint authentication process returned. If they match, the client is assured it has contacted the expected service endpoint. This functions as a protection against phishing by preventing a client from being redirected to an endpoint hosted by a malicious service.

For a sample application that demonstrates identity setting, see Service Identity Sample. For more information about endpoints and endpoint addresses, see Endpoint Addresses.

Note

When you use NT LanMan (NTLM) for authentication, the service identity is not checked because, under NTLM, the client is unable to authenticate the server. NTLM is used when computers are part of a Windows workgroup, or when running an older version of Windows that does not support Kerberos authentication.

When the client initiates a secure channel to send a message to a service over it, the Windows Communication Foundation (WCF) infrastructure authenticates the service, and only sends the message if the service identity matches the identity specified in the endpoint address the client uses.

Identity processing consists of the following stages:

  • At design time, the client developer determines the service's identity from the endpoint's metadata (exposed through WSDL).

  • At runtime, the client application checks the claims of the service's security credentials before sending any messages to the service.

Identity processing on the client is analogous to client authentication on the service. A secure service does not execute code until the client's credentials have been authenticated. Likewise, the client does not send messages to the service until the service's credentials have been authenticated based on what is known in advance from the service's metadata.

The Identity property of the EndpointAddress class represents the identity of the service called by the client. The service publishes the Identity in its metadata. When the client developer runs the Service Model Metadata Utility Tool (Svcutil.exe) against the service endpoint, the generated configuration contains the value of the service's Identity property. The WCF infrastructure (if configured with security) verifies that the service possesses the identity specified.

Note

The metadata contains the expected identity of the service, so it is recommended that you expose the service metadata through secure means, for example, by creating an HTTPS endpoint for the service. For more information, see How to: Secure Metadata Endpoints.

Identity Types

A service can provide five types of identities. Each identity type corresponds to an element that can be contained inside the <identity> element in configuration. The type used depends on the scenario and the service's security requirements. The following table describes each identity type.

Identity type Description Typical scenario

Domain Name System (DNS)

Use this element with X.509 certificates or Windows accounts. It compares the DNS name specified in the credential with the value specified in this element.

A DNS check enables you to use certificates with DNS or subject names. If a certificate is reissued with the same DNS or subject name, then the identity check is still valid. When a certificate is reissued, it gets a new RSA key but retains the same DNS or subject name. This means that clients do not have to update their identity information about the service.

Certificate. The default when ClientCredentialType is set to Certificate.

This element specifies a Base64-encoded X.509 certificate value to compare with the client.

Also use this element when using a CardSpace as a credential to authenticate the service.

This element restricts authentication to a single certificate based upon its thumbprint value. This enables stricter authentication because thumbprint values are unique. This comes with one caveat: If the certificate is reissued with the same Subject name, it also has a new Thumbprint. Therefore, clients are not able to validate the service unless the new thumbprint is known. For more information about finding a certificate's thumbprint, see How to: Retrieve the Thumbprint of a Certificate.

Certificate Reference

Identical to the Certificate option described previously. However, this element enables you to specify a certificate name and store location from which to retrieve the certificate.

Same as the Certificate scenario described previously.

The benefit is that the certificate store location can change.

RSA

This element specifies an RSA key value to compare with the client. This is similar to the certificate option but rather than using the certificate's thumbprint, the certificate's RSA key is used instead.

An RSA check enables you to specifically restrict authentication to a single certificate based upon its RSA key. This enables stricter authentication of a specific RSA key at the expense of the service, which no longer works with existing clients if the RSA key value changes.

User principal name (UPN). The default when the ClientCredentialType is set to Windows and the service process is not running under one of the system accounts.

This element specifies the UPN that the service is running under. See the Kerberos Protocol and Identity section of Overriding the Identity of a Service for Authentication.

This ensures that the service is running under a specific Windows user account. The user account can be either the current logged-on user or the service running under a particular user account.

This setting takes advantage of Windows Kerberos security if the service is running under a domain account within an Active Directory environment.

Service principal name (SPN). The default when the ClientCredentialType is set to Windows and the service process is running under one of the system accounts—LocalService, LocalSystem, or NetworkService.

This element specifies the SPN associated with the service's account. See the Kerberos Protocol and Identity section of Overriding the Identity of a Service for Authentication.

This ensures that the SPN and the specific Windows account associated with the SPN identify the service.

You can use the Setspn.exe tool to associate a machine account for the service's user account.

This setting takes advantage of Windows Kerberos security if the service is running under one of the system accounts or under a domain account that has an associated SPN name with it and the computer is a member of a domain within an Active Directory environment.

Specifying Identity at the Service

Typically, you do not have to set the identity on a service because the selection of a client credential type dictates the type of identity exposed in the service metadata. For more information about how to override or specify service identity, see Overriding the Identity of a Service for Authentication.

Using the <identity> Element in Configuration

If you change the client credential type in the binding previously shown to Certificate, then the generated WSDL contains a Base64 serialized X.509 certificate for the identity value as shown in the following code. This is the default for all client credential types other than Windows.

<Identity xmlns="https://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
 <X509Data>
 <X509Certificate>MIIBxjCCAXSgAwIBAgIQmXJgyu9tro1M98GifjtuoDAJBgUrDgMCHQUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTA2MDUxNzIxNDQyNVoXDTM5MTIzMTIzNTk1OVowKTEQMA4GA1UEChMHQ29udG9zbzEVMBMGA1UEAxMMaWRlbnRpdHkuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBmivcb8hYbh11hqVoDuB7zmJ2y230f/b4e+4P6yXtKKuhUdYcIqc8mAforIM4WWJEVGeJVq9sFEwqrL5Ryid8jMTRwPLvA/x/wvj1gtD1GWJ+aUh2pqieiGL7MWTepHAQBIibUxgOrAOz0j9Xhg0iDFYScdYUjeqI3yZIDC7WbwIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwCQYFKw4DAh0FAANBADB/J2QjdSPL8Doj3pAveCXd/5fY03eo9kUym/Tmb4ubdqsObri0qnYR/n8Wxsa1yJ4Dks6cNBTPS4l5B7zUeNo=</X509Certificate> 
 </X509Data>
</KeyInfo>
</Identity>

You can change the value of the default service identity or change the type of the identity by using the <identity> element in configuration or by setting the identity in code. The following configuration code sets a domain name system (DNS) identity with the value contoso.com.

Setting Identity Programmatically

Your service does not have to explicitly specify an identity, because WCF automatically determines it. However, WCF allows you to specify an identity on an endpoint, if required. The following code adds a new service endpoint with a specific DNS identity.

Dim ep As ServiceEndpoint = myServiceHost.AddServiceEndpoint(GetType(ICalculator), New WSHttpBinding(), String.Empty)
Dim myEndpointAdd As New EndpointAddress(New Uri("https://localhost:8088/calc"), EndpointIdentity.CreateDnsIdentity("contoso.com"))
ep.Address = myEndpointAdd
ServiceEndpoint ep = myServiceHost.AddServiceEndpoint(
                typeof(ICalculator),
                new WSHttpBinding(),
                String.Empty);
EndpointAddress myEndpointAdd = new EndpointAddress(new Uri("https://localhost:8088/calc"),
     EndpointIdentity.CreateDnsIdentity("contoso.com"));
ep.Address = myEndpointAdd;

Specifying Identity at the Client

At design time, a client developer typically uses the ServiceModel Metadata Utility Tool (Svcutil.exe) to generate client configuration. The generated configuration file (intended for use by the client) contains the server's identity. For example, the following code is generated from a service that specifies a DNS identity, as shown in the preceding example. Note that the client's endpoint identity value matches that of the service. In this case, when the client receives the Windows (Kerberos) credentials for the service, it expects the value to be contoso.com.

<configuration>
<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="WSHttpBinding_ICalculator_Windows">
        <security>
          <message clientCredentialType="Windows"/>
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <client>
    <endpoint address="https://localhost:8003/servicemodelsamples/service/dnsidentity"
      binding="wsHttpBinding"
      bindingConfiguration="WSHttpBinding_ICalculator_Windows"
      contract="ICalculator"
      name="WSHttpBinding_ICalculator">
      <identity>
        <dns value="contoso.com" />
      </identity>
    </endpoint>
  </client>
</system.serviceModel>
</configuration>

If, instead of Windows, the service specifies a certificate as the client credential type, then the certificate's DNS property is expected to be the value contoso.com. (Or if the DNS property is null, the certificate's subject name must be contoso.com.)

Using a Specific Value for Identity

The following client configuration file shows how the service's identity is expected to be a specific value. In the following example, the client can communicate with two endpoints. The first is identified with a certificate thumbprint and the second with a certificate RSA key. That is, a certificate that contains only a public key/private key pair, but is not issued by a trusted authority.

<configuration>
<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="WSHttpBinding_ICalculator_Anonymous">
        <security>
          <message clientCredentialType="None" />
        </security>
      </binding >
      </wsHttpBinding>
  </bindings>
  <client>
    <endpoint   
address="https://localhost:8003/servicemodelsamples/service/certificateidentity"
        binding="wsHttpBinding"
        bindingConfiguration="WSHttpBinding_ICalculator_Anonymous"
        contract="ICalculator"
        name="WSHttpBinding_ICalculator1">
      <identity>
        <certificate encodedValue="AwAAAAEAAAAUAAAARwEDOI5fk5i0+TbylJ9k8Kljle8gAAAAAQAAAMoBAAAwggHGMIIBdKADAgECAhCZcmDK722ujUz3waJ+O26gMAkGBSsOAwIdBQAwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3kwHhcNMDYwNTE3MjE0NDI1WhcNMzkxMjMxMjM1OTU5WjApMRAwDgYDVQQKEwdDb250b3NvMRUwEwYDVQQDEwxpZGVudGl0eS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMGaK9xvyFhuHXWGpWgO4HvOYnbLbfR/9vh77g/rJe0oq6FR1hwipzyYB+isgzhZYkRUZ4lWr2wUTCqsvlHKJ3yMxNHA8u8D/H/C+PWC0PUZYn5pSHamqJ6IYvsxZN6kcBAEiJtTGA6sA7PSP1eGDSIMVhJx1hSN6ojfJkgMLtZvAgMBAAGjSzBJMEcGA1UdAQRAMD6AEBLkCS0GHR1PAI1hIdwWZGOhGDAWMRQwEgYDVQQDEwtSb290IEFnZW5jeYIQBjdsAKoAZIoRz7jUqlw19DAJBgUrDgMCHQUAA0EAMH8nZCN1I8vwOiPekC94Jd3/l9jTd6j2RTKb9OZvi5t2qw5uuLSqdhH+fxbGxrXIngOSzpw0FM9LiXkHvNR42g==" />
      </identity>
    </endpoint>
    <endpoint address="https://localhost:8003/servicemodelsamples/service/rsaidentity"
        binding="wsHttpBinding"
        bindingConfiguration="WSHttpBinding_ICalculator_Anonymous"
        contract="ICalculator" 
        name="WSHttpBinding_ICalculator2">
      <identity>
        <rsa value="&lt;RSAKeyValue&gt;&lt;Modulus&gt;wZor3G/IWG4ddYalaA7ge85idstt9H/2+HvuD+sl7SiroVHWHCKnPJgH6KyDOFliRFRniVavbBRMKqy+UconfIzE0cDy7wP8f8L49YLQ9RlifmlIdqaonohi+zFk3qRwEASIm1MYDqwDs9I/V4YNIgxWEnHWFI3qiN8mSAwu1m8=&lt;/Modulus&gt;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;/RSAKeyValue&gt;" />
      </identity>
    </endpoint>
  </client>
</system.serviceModel>
</configuration>

Identity Checking at Run Time

At design time, a client developer determines the server's identity through its metadata. At runtime, the identity check is performed before calling any endpoints on the service.

The identity value is tied to the type of authentication specified by metadata; in other words, the type of credentials used for the service.

If the channel is configured to authenticate using message- or transport-level Secure Sockets Layer (SSL) with X.509 certificates for authentication, the following identity values are valid:

  • DNS. WCF ensures that the certificate provided during the SSL handshake contains a DNS or CommonName (CN) attribute equal to the value specified in the DNS identity on the client. Note that these checks are done in addition to determining the validity of the server certificate. By default, WCF validates that the server certificate is issued by a trusted root authority.

  • Certificate. During the SSL handshake, WCF ensures that the remote endpoint provides the exact certificate value specified in the identity.

  • Certificate Reference. Same as Certificate.

  • RSA. During the SSL handshake, WCF ensures that the remote endpoint provides the exact RSA key specified in the identity.

If the service authenticates using message- or transport-level SSL with a Windows credential for authentication, and negotiates the credential, the following identity values are valid:

  • DNS. The negotiation passes the service's SPN so that the DNS name can be checked. The SPN is in the form host/<dns name>.

  • SPN. An explicit service SPN is returned, for example, host/myservice.

  • UPN. The UPN of the service account. The UPN is in the form username@domain. For example, when the service is running in a user account, it may be username@contoso.com.

Specifying the identity programmatically (using the Identity property) is optional. If no identity is specified, and the client credential type is Windows, the default is SPN with the value set to the hostname part of the service endpoint address prefixed with the "host/" literal. If no identity is specified, and the client credential type is a certificate, the default is Certificate. This applies to both message- and transport-level security.

Identity and Custom Bindings

Because the identity of a service depends on the binding type used, ensure that an appropriate identity is exposed when creating a custom binding. For example, in the following code example, the identity exposed is not compatible with the security type, because the identity for the secure conversation bootstrap binding does not match the identity for the binding on the endpoint. The secure conversation binding sets the DNS identity, while the WindowsStreamSecurityBindingElement sets the UPN or SPN identity.

Dim binding As New CustomBinding()
' The following binding exposes a DNS identity.
binding.Elements.Add(SecurityBindingElement.CreateSecureConversationBindingElement(SecurityBindingElement.CreateIssuedTokenForSslBindingElement(New IssuedSecurityTokenParameters())))

' The following element requires a UPN or SPN identity.
binding.Elements.Add(New WindowsStreamSecurityBindingElement())
binding.Elements.Add(New TcpTransportBindingElement())
CustomBinding binding = new CustomBinding();
// The following binding exposes a DNS identity.
binding.Elements.Add(SecurityBindingElement.
    CreateSecureConversationBindingElement(
    SecurityBindingElement.
    CreateIssuedTokenForSslBindingElement(
    new IssuedSecurityTokenParameters())));

// The following element requires a UPN or SPN identity.
binding.Elements.Add(new WindowsStreamSecurityBindingElement());
binding.Elements.Add(new TcpTransportBindingElement());

For more information about how to stack binding elements correctly for a custom binding, see Creating User-Defined Bindings. For more information about creating a custom binding with the SecurityBindingElement, see How to: Create a SecurityBindingElement for a Specified Authentication Mode.

See Also

Tasks

How to: Create a SecurityBindingElement for a Specified Authentication Mode
How to: Create a Custom Client Identity Verifier
How to: Retrieve the Thumbprint of a Certificate

Concepts

How to: Create a Custom Binding Using the SecurityBindingElement
Selecting a Credential Type
Working with Certificates
Creating User-Defined Bindings

Other Resources

ServiceModel Metadata Utility Tool (Svcutil.exe)