Nachrichtensicherheit mit einem Windows-Client ohne Anmeldeinformationen-AushandlungMessage Security with a Windows Client without Credential Negotiation

Das folgende Szenario zeigt einen Windows Communication Foundation (WCF)-Client und Dienst, die durch das Kerberos-Protokoll gesichert.The following scenario shows a Windows Communication Foundation (WCF) client and service secured by the Kerberos protocol.

Sowohl der Dienst als auch der Client befinden sich in der gleichen Domäne bzw. in den gleichen vertrauenswürdigen Domänen.Both the service and the client are in the same domain or trusted domains.

Hinweis

Der Unterschied zwischen diesem Szenario und Nachrichtensicherheit mit einem Windows-Client ist, dass dieses Szenario die Dienstanmeldeinformationen mit dem Dienst vor dem Senden der Anwendungsnachricht nicht verhandelt werden.The difference between this scenario and Message Security with a Windows Client is that this scenario does not negotiate the service credential with the service prior to sending the application message. Da hierzu das Kerberos-Protokoll erforderlich ist, muss für dieses Szenario auch eine Windows-Domänenumgebung vorhanden sein.Additionally, because this requires the Kerberos protocol, this scenario requires a Windows domain environment.

Nachrichtensicherheit ohne Anmeldeinformationen-AushandlungMessage security without credential negotiation

MerkmalCharacteristic BeschreibungDescription
SicherheitsmodusSecurity Mode MeldungMessage
InteroperabilitätInteroperability Ja, WS-Security mit Clients mit Kerberos-TokenprofilkompatibilitätYes, WS-Security with Kerberos token-profile compatible clients
Authentifizierung (Server)Authentication (Server) Gegenseitige Authentifizierung des Servers und des ClientsMutual authentication of the server and client
Authentifizierung (Client)Authentication (Client) Gegenseitige Authentifizierung des Servers und des ClientsMutual authentication of the server and client
IntegritätIntegrity JaYes
VertraulichkeitConfidentiality JaYes
TransportTransport HTTPHTTP
BindungBinding WSHttpBinding

DienstService

Der folgende Code und die folgende Konfiguration werden unabhängig voneinander ausgeführt.The following code and configuration are meant to run independently. Führen Sie einen der folgenden Schritte aus:Do one of the following:

  • Erstellen Sie einen separaten Dienst, indem Sie den Code ohne Konfiguration verwenden.Create a stand-alone service using the code with no configuration.

  • Erstellen Sie mit der angegebenen Konfiguration einen Dienst, aber definieren Sie keine Endpunkte.Create a service using the supplied configuration, but do not define any endpoints.

CodeCode

Der folgende Code dient zum Erstellen eines Dienstendpunkts mit Nachrichtensicherheit.The following code creates a service endpoint that uses message security. Mit diesem Code wird das Aushandeln der Dienstanmeldeinformationen sowie das Einrichten eines Sicherheitskontexttokens (Security Context Token, SCT) deaktiviert.The code disables service credential negotiation, and the establishment of a security context token (SCT).

Hinweis

Zur Verwendung des Windows-Anmeldeinformationstyps ohne Aushandlung muss das Benutzerkonto des Diensts Zugriff auf den bei der Active Directory-Domäne registrierten Dienstprinzipalnamen (Service Principal Name, SPN) haben.To use the Windows credential type without negotiation, the service's user account must have access to service principal name (SPN) that is registered with the Active Directory domain. Dazu gibt es zwei Möglichkeiten:You can do this in two ways:

  1. Verwenden Sie das NetworkService-Konto oder das LocalSystem-Konto, um den Dienst auszuführen.Use the NetworkService or LocalSystem account to run your service. Da diese Konten Zugriff auf die Computer-SPN, die hergestellt wird haben, wenn der Computer die Active Directory-Domäne beitritt, generiert WCF automatisch den richtige SPN-Element im Endpunkt des Diensts in den Dienstmetadaten (Web Services Description Language oder WSDL).Because those accounts have access to the machine SPN that is established when the machine joins the Active Directory domain, WCF automatically generates the proper SPN element inside the service's endpoint in the service's metadata (Web Services Description Language, or WSDL).

  2. Verwenden Sie ein beliebiges Active Directory-Domänenkonto, um den Dienst auszuführen.Use an arbitrary Active Directory domain account to run your service. In diesem Fall muss für das Domänenkonto ein SPN eingerichtet werden.In this case, you need to establish an SPN for that domain account. Eine mögliche Vorgehensweise hierzu besteht in der Verwendung des Tools Setspn.exe.One way of doing this is to use the Setspn.exe utility tool. Sobald der SPN für das Konto des Diensts erstellt wird, konfigurieren Sie WCF um, dass dieser SPN für den Dienst Clients über seine Metadaten (WSDL) veröffentlicht.Once the SPN is created for the service's account, configure WCF to publish that SPN to the service's clients through its metadata (WSDL). Legen Sie hierzu die Endpunktidentität für den angezeigten Endpunkt entweder mit einer Anwendungskonfigurationsdatei oder mit Code fest.This is done by setting the endpoint identity for the exposed endpoint, either though an application configuration file or code. Im folgenden Beispiel wird die Identität programmgesteuert veröffentlicht:The following example publishes the identity programmatically.

Weitere Informationen zu SPNs, die Kerberos-Protokoll und Active Directory finden Sie unter technische Kerberos-Ergänzung für Windows.For more information about SPNs, the Kerberos protocol, and Active Directory, see Kerberos Technical Supplement for Windows. Weitere Informationen über Identitäten Endpunkt finden Sie unter SecurityBindingElement-Authentifizierungsmodi.For more information about endpoint identities, see SecurityBindingElement Authentication Modes.

// Create the service host.
ServiceHost myServiceHost = new ServiceHost(typeof(Calculator));

// Create the binding.
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType =
     MessageCredentialType.Windows;

// Disable credential negotiation and establishment of the
// security context.
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Message.EstablishSecurityContext = false;

// Create a URI for the endpoint address.
Uri httpUri = new Uri("http://localhost/Calculator");

// Create the EndpointAddress with the SPN for the Identity.
EndpointAddress ea = new EndpointAddress(httpUri,
    EndpointIdentity.CreateSpnIdentity("service_spn_name"));

// Get the contract from the ICalculator interface (not shown here).
// See the sample applications for an example of the ICalculator.
ContractDescription contract = ContractDescription.GetContract(
    typeof(ICalculator));

// Create a new ServiceEndpoint.
ServiceEndpoint se = new ServiceEndpoint(contract, binding, ea);

// Add the service endpoint to the service.
myServiceHost.Description.Endpoints.Add(se);

// Open the service.
myServiceHost.Open();
Console.WriteLine("Listening...");
Console.ReadLine();

// Close the service. 
myServiceHost.Close();
' Create the service host.
Dim myServiceHost As New ServiceHost(GetType(ServiceModel.Calculator))

' Create the binding.
Dim binding As New WSHttpBinding()
binding.Security.Mode = SecurityMode.Message
binding.Security.Message.ClientCredentialType = _
   MessageCredentialType.Windows

' Disable credential negotiation and establishment of the
' security context.
binding.Security.Message.NegotiateServiceCredential = False
binding.Security.Message.EstablishSecurityContext = False

' Create a URI for the endpoint address.
Dim httpUri As New Uri("http://localhost/Calculator")

' Create the EndpointAddress with the SPN for the Identity.
Dim ea As New EndpointAddress(httpUri, _
EndpointIdentity.CreateSpnIdentity("service_spn_name"))

' Get the contract from the ICalculator interface (not shown here).
' See the sample applications for an example of the ICalculator.
Dim contract As ContractDescription = ContractDescription.GetContract(GetType(ICalculator))

' Create a new ServiceEndpoint.
Dim se As New ServiceEndpoint(contract, binding, ea)

' Add the service endpoint to the service.
myServiceHost.Description.Endpoints.Add(se)

' Open the service.
myServiceHost.Open()
Console.WriteLine("Listening...")
Console.ReadLine()

' Close the service. 
myServiceHost.Close()

KonfigurationConfiguration

Anstelle des Codes kann die folgende Konfiguration verwendet werden:The following configuration can be used instead of the code.

<?xml version="1.0" encoding="utf-8"?>  
<configuration>  
  <system.serviceModel>  
    <behaviors />  
    <services>  
      <service behaviorConfiguration="" name="ServiceModel.Calculator">  
        <endpoint address="http://localhost/Calculator"   
                  binding="wsHttpBinding"  
                  bindingConfiguration="KerberosBinding"  
                  name="WSHttpBinding_ICalculator"  
                  contract="ServiceModel.ICalculator"   
                  listenUri="net.tcp://localhost/metadata" >  
         <identity>  
            <servicePrincipalName value="service_spn_name" />  
         </identity>  
        </endpoint>  
      </service>  
    </services>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="KerberosBinding">  
          <security>  
            <message negotiateServiceCredential="false"   
                     establishSecurityContext="false" />  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <client />  
  </system.serviceModel>  
</configuration>  

ClientClient

Der folgende Code und die folgende Konfiguration werden unabhängig voneinander ausgeführt.The following code and configuration are meant to run independently. Führen Sie einen der folgenden Schritte aus:Do one of the following:

  • Erstellen Sie mit dem Code (und Clientcode) einen eigenständigen Client.Create a stand-alone client using the code (and client code).

  • Erstellen Sie einen Client, der keine Endpunktadressen definiert.Create a client that does not define any endpoint addresses. Verwenden Sie stattdessen den Clientkonstruktor, der den Konfigurationsnamen als Argument verwendet.Instead, use the client constructor that takes the configuration name as an argument. Beispiel:For example:

    CalculatorClient cc = new CalculatorClient("EndpointConfigurationName");
    
    Dim cc As New CalculatorClient("EndpointConfigurationName")
    

CodeCode

Der folgende Code dient zum Konfigurieren des Clients.The following code configures the client. Der Sicherheitsmodus ist auf Nachrichtensicherheit, der Typ der Clientanmeldeinformationen auf Windows festgelegt.The security mode is set to Message, and the client credential type is set to Windows. Die Eigenschaften NegotiateServiceCredential und EstablishSecurityContext sind auf false festgelegt.Note that the NegotiateServiceCredential and EstablishSecurityContext properties are set to false.

Hinweis

Zur Verwendung des Windows-Anmeldeinformationstyps ohne Aushandlung muss der Client vor dem Starten der Kommunikation mit dem Dienst mit dem Konto-SPN des Diensts konfiguriert werden.To use Windows credential type without negotiation, the client must be configured with the service's account SPN prior to commencing the communication with the service. Der SPN wird vom Client zum Abrufen des Kerberos-Tokens verwendet, um damit die Kommunikation mit dem Dienst zu authentifizieren und zu sichern.The client uses the SPN to get the Kerberos token to authenticate and secure the communication with the service. Im folgenden Beispiel wird das Konfigurieren des Clients mit dem SPN des Diensts veranschaulicht.The following sample shows how to configure the client with the service's SPN. Bei Verwendung der ServiceModel Metadata Utility Tool (Svcutil.exe) um den Client zu generieren, den SPN des Diensts wird automatisch weitergegeben werden an den Client aus Dienstmetadaten (WSDL), wenn die Metadaten des Diensts enthält Diese Informationen.If you are using the ServiceModel Metadata Utility Tool (Svcutil.exe) to generate the client, the service's SPN will be automatically propagated to the client from the service's metadata (WSDL), if the service's metadata contains that information. Weitere Informationen zur Konfiguration des Diensts, um einen SPN in den Metadaten des Diensts eingeschlossen werden sollen finden Sie unter im Abschnitt "Dienst" weiter unten in diesem Thema.For more information about how to configure the service to include its SPN in the service's metadata, see the "Service" section later in this topic .

Weitere Informationen über SPNs, Kerberos und Active Directory finden Sie unter technische Kerberos-Ergänzung für Windows.For more information about SPNs, Kerberos, and Active Directory, see Kerberos Technical Supplement for Windows. Weitere Informationen über Identitäten Endpunkt finden Sie unter SecurityBindingElement-Authentifizierungsmodi Thema.For more information about endpoint identities, see SecurityBindingElement Authentication Modes topic.

// Create the binding.
WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType =
    MessageCredentialType.Windows;

// Disable credential negotiation and the establishment of 
// a security context.
myBinding.Security.Message.NegotiateServiceCredential = false;
myBinding.Security.Message.EstablishSecurityContext = false;

// Create the endpoint address and set the SPN identity.
// The SPN must match the identity of the service's SPN.
// If using SvcUtil to generate a configuration file, the SPN
// will be published as the <servicePrincipalName> element under the
// <identity> element.
EndpointAddress ea = new EndpointAddress(
new Uri("http://machineName/Calculator"),
EndpointIdentity.CreateSpnIdentity("service_spn_name"));

// Create the client. 
CalculatorClient cc =
    new CalculatorClient(myBinding, ea);

// Begin using the client.

try
{
    cc.Open();
    Console.WriteLine(cc.Add(200, 1111));
    Console.ReadLine();

    // Close the client.
    cc.Close();
}
' Create the binding.
Dim myBinding As New WSHttpBinding()
myBinding.Security.Mode = SecurityMode.Message
myBinding.Security.Message.ClientCredentialType = _
   MessageCredentialType.Windows

' Disable credential negotiation and the establishment of 
' a security context.
myBinding.Security.Message.NegotiateServiceCredential = False
myBinding.Security.Message.EstablishSecurityContext = False

' Create the endpoint address and set the SPN identity.
' The SPN must match the identity of the service's SPN.
' If using SvcUtil to generate a configuration file, the SPN
' will be published as the <servicePrincipalName> element under the
' <identity> element.
Dim ea As New EndpointAddress(New Uri("http://machineName/calculator"), _
EndpointIdentity.CreateSpnIdentity("service_spn_name"))

' Create the client. 
Dim cc As New CalculatorClient(myBinding, ea)

' Begin using the client.
Try
    cc.Open()

    Console.WriteLine(cc.Add(100, 11))
    Console.ReadLine()

    ' Close the client.
    cc.Close()
Catch tex As TimeoutException
    Console.WriteLine(tex.Message)
    cc.Abort()
Catch cex As CommunicationException
    Console.WriteLine(cex.Message)
    cc.Abort()
Finally
    Console.WriteLine("Closed the client")
    Console.ReadLine()
End Try

KonfigurationConfiguration

Der folgende Code dient zum Konfigurieren des Clients.The following code configures the client. Beachten Sie, dass die <ServicePrincipalName > Element muss festgelegt werden, um den SPN des Diensts überein, wie für das Dienstkonto in Active Directory-Domäne registriert.Note that the <servicePrincipalName> element must be set to match the service's SPN as registered for the service's account in the Active Directory domain.

<?xml version="1.0" encoding="utf-8"?>  
<configuration>  
  <system.serviceModel>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="WSHttpBinding_ICalculator" >  
          <security mode="Message">  
            <message clientCredentialType="Windows"   
                     negotiateServiceCredential="false"  
                     establishSecurityContext="false" />  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <client>  
      <endpoint address="http://localhost/Calculator"   
                binding="wsHttpBinding"  
                bindingConfiguration="WSHttpBinding_ICalculator"  
                contract="ICalculator"  
                name="WSHttpBinding_ICalculator">  
        <identity>  
          <servicePrincipalName value="service_spn_name" />  
        </identity>  
      </endpoint>  
    </client>  
  </system.serviceModel>  
</configuration>  

Siehe auchSee Also

Übersicht über die SicherheitSecurity Overview
Dienstidentität und AuthentifizierungService Identity and Authentication
Sicherheitsmodell für Windows Server AppFabricSecurity Model for Windows Server App Fabric