Freigeben über


Nachrichtensicherheit mit einem Windows-Client ohne Anmeldeinformationen-Aushandlung

Das folgende Szenario zeigt einen durch das Kerberos-Protokoll gesicherten Windows Communication Foundation (WCF)-Client und -Dienst.

Sowohl der Dienst als auch der Client befinden sich in der gleichen Domäne bzw. in den gleichen vertrauenswürdigen Domänen.

ms735117.note(de-de,VS.100).gifHinweis:
Der Unterschied zwischen diesem Szenario und Nachrichtensicherheit über einen Windows-Client besteht darin, dass in diesem Szenario vor dem Senden der Anwendungsnachricht keine Aushandlung der Dienstanmeldeinformationen mit dem Dienst stattfindet. Da hierzu das Kerberos-Protokoll erforderlich ist, muss für dieses Szenario auch eine Windows-Domänenumgebung vorhanden sein.

Nachrichtensicherheit ohne Anmeldeinformationen-Aushandlung

Merkmal Beschreibung

Sicherheitsmodus

Nachricht

Interoperabilität

Ja, WS-Security mit Clients mit Kerberos-Tokenprofilkompatibilität

Authentifizierung (Server)

Gegenseitige Authentifizierung des Servers und des Clients

Authentifizierung (Client)

Gegenseitige Authentifizierung des Servers und des Clients

Integrität

Ja

Vertraulichkeit

Ja

Transport

HTTP

Bindung

WSHttpBinding

Dienst

Der folgende Code und die folgende Konfiguration werden unabhängig voneinander ausgeführt. Führen Sie einen der folgenden Schritte aus:

  • Erstellen Sie einen separaten Dienst, indem Sie den Code ohne Konfiguration verwenden.

  • Erstellen Sie mit der angegebenen Konfiguration einen Dienst, aber definieren Sie keine Endpunkte.

Code

Der folgende Code dient zum Erstellen eines Dienstendpunkts mit Nachrichtensicherheit. Mit diesem Code wird das Aushandeln der Dienstanmeldeinformationen sowie das Einrichten eines Sicherheitskontexttokens (Security Context Token, SCT) deaktiviert.

ms735117.note(de-de,VS.100).gifHinweis:
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. Dazu gibt es zwei Möglichkeiten:

  1. Verwenden Sie das NetworkService-Konto oder das LocalSystem-Konto, um den Dienst auszuführen. Da diese Konten über Zugriff auf den beim Hinzufügen des Computers zur Active Directory-Domäne erstellten Computer-SPN verfügen, wird von WCF automatisch das entsprechende SPN-Element im Endpunkt des Diensts in den Dienstmetadaten (Web Services Description Language, WSDL) generiert.

  2. Verwenden Sie ein beliebiges Active Directory-Domänenkonto, um den Dienst auszuführen. In diesem Fall muss für das Domänenkonto ein SPN eingerichtet werden. Eine mögliche Vorgehensweise hierzu besteht in der Verwendung des Tools Setspn.exe. Konfigurieren Sie WCF nach dem Erstellen des SPNs für das Konto so, dass dieser SPN für die Clients des Diensts über seine Metadaten (WSDL) veröffentlicht wird. Legen Sie hierzu die Endpunktidentität für den angezeigten Endpunkt entweder mit einer Anwendungskonfigurationsdatei oder mit Code fest. Im folgenden Beispiel wird die Identität programmgesteuert veröffentlicht:

Weitere Informationen über zu SPNs, zum Kerberos-Protokoll sowie zu Active Directory finden Sie unter Technische Kerberos-Ergänzung für Windows (möglicherweise in englischer Sprache). Weitere Informationen über zu Endpunktidentitäten finden Sie unter SecurityBindingElement-Authentifizierungsmodi.

' 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("https://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()
// 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("https://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();

Konfiguration

Anstelle des Codes kann die folgende Konfiguration verwendet werden:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <behaviors />
    <services>
      <service behaviorConfiguration="" name="ServiceModel.Calculator">
        <endpoint address="https://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>

Client

Der folgende Code und die folgende Konfiguration werden unabhängig voneinander ausgeführt. Führen Sie einen der folgenden Schritte aus:

  • Erstellen Sie mit dem Code (und Clientcode) einen eigenständigen Client.

  • Erstellen Sie einen Client, der keine Endpunktadressen definiert. Verwenden Sie stattdessen den Clientkonstruktor, der den Konfigurationsnamen als Argument verwendet. Beispiel:

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

Code

Der folgende Code dient zum Konfigurieren des Clients. Der Sicherheitsmodus ist auf Nachrichtensicherheit, der Typ der Clientanmeldeinformationen auf Windows festgelegt. Die Eigenschaften NegotiateServiceCredential und EstablishSecurityContext sind auf false festgelegt.

ms735117.note(de-de,VS.100).gifHinweis:
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. Der SPN wird vom Client zum Abrufen des Kerberos-Tokens verwendet, um damit die Kommunikation mit dem Dienst zu authentifizieren und zu sichern. Im folgenden Beispiel wird das Konfigurieren des Clients mit dem SPN des Diensts veranschaulicht. Wird ServiceModel Metadata Utility-Tool (Svcutil.exe) zum Generieren des Clients verwendet, wird der SPN des Diensts aus den Dienstmetadaten (WSDL) automatisch an den Client weitergegeben, sofern diese Information in den Metadaten des Diensts enthalten ist. Weitere Informationen über zum Konfigurieren des Diensts, sodass der SPN in die Dienstmetadaten aufgenommen wird, finden Sie weiter unten in diesem Thema im Abschnitt "Dienst".

Weitere Informationen zu SPNs, Kerberos und Active Directory finden Sie unter Kerberos Technical Supplement for Windows. Weitere Informationen über zu Endpunktidentitäten finden Sie im Thema SecurityBindingElement-Authentifizierungsmodi.

' 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
// 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();
}

Konfiguration

Der folgende Code dient zum Konfigurieren des Clients. Das <ServicePrincipalName>-Element muss so festgelegt werden, dass es dem für das Dienstkonto in der Active Directory-Domäne registrierten Dienst-SPN entspricht.

<?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="https://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 auch

Konzepte

Sicherheitsübersicht
Dienstidentität und Authentifizierung

Weitere Ressourcen

Sicherheitsmodell für Windows Server AppFabric