Freigeben über


Vorgehensweise: Sichern eines Dienstes mit Windows-Anmeldeinformationen

In diesem Thema wird gezeigt, wie die Übertragungssicherheit für einen Windows Communication Foundation (WCF)-Dienst in einer Windows-Domäne aktiviert und von Clients in der gleichen Domäne aufgerufen wird. Weitere Informationen über zu diesem Szenario finden Sie unter Transportsicherheit mit Windows-Authentifizierung. Eine Beispielanwendung finden Sie im WSHttpBinding-Beispiel.

In diesem Thema wird vorausgesetzt, dass Sie über eine vorhandene Vertragsschnittstelle verfügen und die Implementierung bereits definiert wurde, da hier auf diese beiden Punkte aufgebaut wird. Sie können auch einen vorhandenen Dienst und Client ändern.

Sie können einen Dienst mit Windows-Anmeldeinformationen vollständig im Code sichern. Alternativ können Sie bei Verwendung einer Konfigurationsdatei einige Teile des Codes weglassen. In diesem Thema werden beide Methoden gezeigt. Verwenden Sie jedoch stets nur eine der Methoden.

In den ersten drei Prozeduren wird gezeigt, wie der Dienst unter Verwendung von Code gesichert wird. Die vierte und fünfte Prozedur zeigen, wie dies mit einer Konfigurationsdatei erreicht wird.

Mithilfe von Code

Den vollständigen Code für Dienst und Client finden Sie im Beispielabschnitt am Ende dieses Themas.

Die erste Prozedur führt Sie durch die Schritte zum Erstellen und Konfigurieren einer WSHttpBinding-Klasse im Code. Für die Bindung wird der HTTP-Transport verwendet. Die gleiche Bindung wird auf dem Client verwendet.

So erstellen Sie eine WSHttpBinding, die Windows-Anmeldeinformationen und Nachrichtensicherheit verwendet

  1. Der Code dieser Prozedur wird im Dienstcode des Beispielabschnitts am Anfang der Run-Methode der Test-Klasse eingefügt.

  2. Erstellen Sie eine Instanz der WSHttpBinding-Klasse.

  3. Legen Sie die Mode-Eigenschaft der WsHttpSecurity-Klasse auf Message fest.

  4. Legen Sie die ClientCredentialType-Eigenschaft der MessageSecurityOverHttp-Klasse auf Windows fest.

  5. Für diese Prozedur wird der folgende Code verwendet:

    Dim myBinding As New WSHttpBinding()
    myBinding.Security.Mode = SecurityMode.Message
    myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows
    
    // First procedure:
    // create a WSHttpBinding that uses Windows credentials and message security
    WSHttpBinding myBinding = new WSHttpBinding();
    myBinding.Security.Mode = SecurityMode.Message;
    myBinding.Security.Message.ClientCredentialType =
        MessageCredentialType.Windows;
    

Verwenden der Bindung in einem Dienst

Dies ist die zweite Prozedur; in dieser Prozedur wird die Verwendung der Bindung in einem selbst gehosteten Dient veranschaulicht. Weitere Informationen über über das Hosting von Diensten finden Sie unter Hosting-Dienste.

So verwenden Sie eine Bindung in einem Dienst

  1. Fügen Sie den Code dieser Prozedur nach dem Code der vorherigen Prozedur ein.

  2. Erstellen Sie eine Type-Variable mit der Bezeichnung contractType, und weisen Sie ihr den Typ der Schnittstelle (ICalculator) zu. Verwenden Sie für Visual Basic den Operator GetType und für C# das Schlüsselwort typeof.

  3. Erstellen Sie eine zweite Type-Variable mit der Bezeichnung serviceType, und weisen Sie ihr den Typ des implementierten Vertrags (Calculator) zu.

  4. Erstellen Sie eine Instanz der Uri-Klasse mit der Bezeichnung baseAddress mit der Basisadresse des Dienstes. Die Basisadresse muss ein Schema haben, das mit dem Transport übereinstimmt. In diesem Fall ist das Transportschema HTTP, und die Adresse enthält den speziellen Uniform Resource Identifier (URI) "localhost" und eine Anschlussnummer (8036) sowie eine Basisendpunktadresse ("serviceModelSamples/): https://localhost:8036/serviceModelSamples/.

  5. Erstellen Sie eine Instanz der ServiceHost-Klasse mit der serviceType-Variablen und der baseAddress-Variablen.

  6. Fügen Sie dem Dienst einen Endpunkt mit contractType, Bindung und einem Endpunktnamen (secureCalculator) hinzu. Ein Client muss beim Initiieren eines Aufrufs zum Dienst die Basisadresse und den Endpunktnamen verketten.

  7. Starten Sie den Dienst, indem Sie die Open-Methode aufrufen. Der Code für diese Prozedur wird hier gezeigt:

    ' Create the Type instances for later use and the URI for 
    ' the base address.
    Dim contractType As Type = GetType(ICalculator)
    Dim serviceType As Type = GetType(Calculator)
    Dim baseAddress As New Uri("https://localhost:8036/serviceModelSamples/")
    
    ' Create the ServiceHost and add an endpoint, then start
    ' the service.
    Dim myServiceHost As New ServiceHost(serviceType, baseAddress)
    myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator")
    myServiceHost.Open()
    
    // 2nd Procedure:
    // Use the binding in a service
    // Create the Type instances for later use and the URI for 
    // the base address.
    Type contractType = typeof(ICalculator);
    Type serviceType = typeof(Calculator);
    Uri baseAddress = new
        Uri("https://localhost:8036/SecuritySamples/");
    
    // Create the ServiceHost and add an endpoint, then start
    // the service.
    ServiceHost myServiceHost =
        new ServiceHost(serviceType, baseAddress);
    myServiceHost.AddServiceEndpoint
        (contractType, myBinding, "secureCalculator");
    
    //enable metadata
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    smb.HttpGetEnabled = true;
    myServiceHost.Description.Behaviors.Add(smb);
    
    myServiceHost.Open();
    

Verwenden der Bindung in einem Client

Diese Prozedur zeigt die Generierung eines Proxys, der mit dem Dienst kommuniziert. Der Proxy wird mit dem ServiceModel Metadata Utility-Tool (Svcutil.exe) generiert. Zur Erstellung des Proxys werden die Dienstmetadaten verwendet.

Durch diese Prozedur wird auch eine Instanz der WSHttpBinding-Klasse erstellt, um mit dem Dienst zu kommunizieren. Anschließend wird der Dienst aufgerufen.

In diesem Beispiel wird zum Erstellen des Clients nur Code verwendet. Alternativ können Sie eine Konfigurationsdatei verwenden. Dies wird im Abschnitt nach dieser Prozedur veranschaulicht.

So verwenden Sie eine Bindung in einem Client mit Code

  1. Verwenden Sie das SvcUtil.exe-Tool, um den Proxycode aus den Metadaten des Diensts zu generieren. Weitere Informationen finden Sie unter Gewusst wie: Erstellen eines Windows Communication Foundation-Clients. Der generierte Proxycode erbt von der ClientBase-Klasse, wodurch sichergestellt wird, dass jeder Client über die erforderlichen Konstruktoren, Methoden und Eigenschaften für die Kommunikation mit einem WCF-Dienst verfügt. In diesem Beispiel enthält der generierte Code die CalculatorClient-Klasse, die die ICalculator-Schnittstelle für die Kompatibilität mit dem Dienstcode implementiert.

  2. Der Code dieser Prozedur wird am Anfang der Main-Methode des Clientprogramms eingefügt.

  3. Erstellen Sie eine Instanz der WSHttpBinding-Klasse und legen Sie ihren Sicherheitsmodus auf Message und ihren Clientanmeldeinformationstyp auf Windows fest. Im Beispiel wird die Variable clientBinding genannt.

  4. Erstellen Sie eine Instanz der EndpointAddress-Klasse mit der Bezeichnung serviceAddress. Initialisieren Sie die Instanz mit der mit dem Endpunktnamen verketteten Basisadresse.

  5. Erstellen Sie eine Instanz der generierten Clientklasse mit der serviceAddress-Variablen und der clientBinding-Variablen.

  6. Rufen Sie die Open-Methode auf, wie im folgenden Code dargestellt.

  7. Rufen Sie den Dienst auf, und zeigen Sie die Ergebnisse an.

    Dim b As New WSHttpBinding(SecurityMode.Message)
    b.Security.Message.ClientCredentialType = MessageCredentialType.Windows
    
    Dim ea As New EndpointAddress("net.tcp://machinename:8036/endpoint")
    Dim cc As New CalculatorClient(b, ea)
    cc.Open()
    
    ' Alternatively, use a binding name from a configuration file generated by the
    ' SvcUtil.exe tool to create the client. Omit the binding and endpoint address 
    ' because that information is provided by the configuration file.
    ' CalculatorClass cc = new CalculatorClient("ICalculator_Binding")
    
    // 3rd Procedure:
    //  Creating a binding and using it in a service
    
    // To run using config, comment the following lines, and uncomment out the code
    // following this section
    WSHttpBinding b = new WSHttpBinding(SecurityMode.Message);
    b.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
    
    EndpointAddress ea = new EndpointAddress("Http://localhost:8036/SecuritySamples/secureCalculator");
    CalculatorClient cc = new CalculatorClient(b, ea);
    cc.Open();
    
    // Now call the service and display the results
    // Call the Add service operation.
    double value1 = 100.00D;
    double value2 = 15.99D;
    double result = cc.Add(value1, value2);
    Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
    
    // Closing the client gracefully closes the connection and cleans up resources.
    cc.Close();
    

Verwenden der Konfigurationsdatei

Anstelle der Erstellung der Bindung mithilfe von prozeduralem Code können Sie auch den folgenden Code für den Bindungsabschnitt der Konfigurationsdatei verwenden.

Sollten Sie noch keinen Dienst definiert haben, lesen Sie unter Entwerfen und Implementieren von Diensten sowie unter Konfigurieren von Diensten nach.

Hinweis   Dieser Konfigurationscode wird sowohl in der Dienst- als auch in der Clientkonfigurationsdatei verwendet.

So aktivieren Sie mit der Konfiguration Übertragungssicherheit für einen Dienst in einer Windows-Domäne

  1. Fügen Sie dem <bindings>-Elementabschnitt der Konfigurationsdatei ein <wsHttpBinding>-Element hinzu.

  2. Fügen Sie ein <binding>-Element dem <WSHttpBinding>-Element hinzu, und legen Sie das configurationName-Attribut auf einen für Ihre Anwendung geeigneten Wert fest.

  3. Fügen Sie ein <security>-Element hinzu, und legen Sie das mode-Attribut auf "Message" fest.

  4. Fügen Sie ein <message>-Element hinzu, und legen Sie das clientCredentialType-Attribut auf "Windows" fest.

  5. Ersetzen Sie in der Konfigurationsdatei des Diensts den <bindings>-Abschnitt durch den folgenden Code. Sollten Sie noch nicht über eine Dienstkonfigurationsdatei verfügen, lesen Sie unter Verwenden von Bindungen, um Dienste und Clients zu konfigurieren nach.

    <bindings>
      <wsHttpBinding>
       <binding name = "wsHttpBinding_Calculator">
         <security mode="Message">
           <message clientCredentialType="Windows"/>
         </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    

Verwenden der Bindung in einem Client

In dieser Prozedur wird die Generierung zweier Dateien veranschaulicht: einem Proxy, der mit dem Dienst kommuniziert, und einer Konfigurationsdatei. Darüber hinaus werden auch Änderungen am Clientprogramm beschrieben – der dritten Datei, die auf dem Client verwendet wird.

So verwenden Sie eine Bindung für einen Client mit Konfiguration

  1. Verwenden Sie das SvcUtil.exe-Tool, um den Proxycode und die Konfigurationsdatei aus den Metadaten des Diensts zu generieren. Weitere Informationen finden Sie unter Gewusst wie: Erstellen eines Windows Communication Foundation-Clients.

  2. Ersetzen Sie den <Bindings>-Abschnitt der generierten Konfigurationsdatei durch den Konfigurationscode aus dem vorherigen Abschnitt.

  3. Prozeduraler Code wird am Anfang der Main-Methode des Clientprogramms eingefügt.

  4. Erstellen Sie eine Instanz der generierten Clientklasse, und geben Sie den Namen der Bindung in der Konfigurationsdatei als Eingabeparameter weiter.

  5. Rufen Sie die Open-Methode auf, wie im folgenden Code dargestellt:

  6. Rufen Sie den Dienst auf, und zeigen Sie die Ergebnisse an.

    // 4th Procedure:
    //  Using config instead of the binding-related code
    // In this case, use a binding name from a configuration file generated by the
    // SvcUtil.exe tool to create the client. Omit the binding and endpoint address 
    // because that information is provided by the configuration file.
    
    CalculatorClient cc = new CalculatorClient("ICalculator_Binding");
    cc.Open();
    
    // Now call the service and display the results
    // Call the Add service operation.
    double value1 = 100.00D;
    double value2 = 15.99D;
    double result = cc.Add(value1, value2);
    Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
    
    // Closing the client gracefully closes the connection and cleans up resources.
    cc.Close();
    

Beispiel

using System;
using System.Collections;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Security.Permissions;

[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
namespace Microsoft.Security.Samples
{
    public class Test
    {
        static void Main()
        {
            Test t = new Test();
            Console.WriteLine("Starting....");
            t.Run();

        }

        private void Run()
        {
            // First procedure:
            // create a WSHttpBinding that uses Windows credentials and message security
            WSHttpBinding myBinding = new WSHttpBinding();
            myBinding.Security.Mode = SecurityMode.Message;
            myBinding.Security.Message.ClientCredentialType =
                MessageCredentialType.Windows;

            // 2nd Procedure:
            // Use the binding in a service
            // Create the Type instances for later use and the URI for 
            // the base address.
            Type contractType = typeof(ICalculator);
            Type serviceType = typeof(Calculator);
            Uri baseAddress = new
                Uri("https://localhost:8036/SecuritySamples/");

            // Create the ServiceHost and add an endpoint, then start
            // the service.
            ServiceHost myServiceHost =
                new ServiceHost(serviceType, baseAddress);
            myServiceHost.AddServiceEndpoint
                (contractType, myBinding, "secureCalculator");

            //enable metadata
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            myServiceHost.Description.Behaviors.Add(smb);

            myServiceHost.Open();
            Console.WriteLine("Listening");
            Console.WriteLine("Press Enter to close the service");
            Console.ReadLine();
            myServiceHost.Close();
        }
    }

    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double a, double b);
    }

    public class Calculator : ICalculator
    {
        public double Add(double a, double b)
        {
            return a + b;
        }
    }
}

Siehe auch

Aufgaben

Gewusst wie: Erstellen eines Windows Communication Foundation-Clients

Verweis

WSHttpBinding

Konzepte

ServiceModel Metadata Utility-Tool (Svcutil.exe)
Sichern von Diensten
Sicherheitsübersicht