Vorgehensweise: Sichern von Metadatenendpunkten

Metadaten für einen Dienst können vertrauliche Informationen über Ihre Anwendung enthalten, die böswillige Benutzer für ihre Zwecke missbrauchen können. Die Consumer Ihres Diensts benötigen möglicherweise auch einen sicheren Mechanismus für den Zugriff auf Metadaten über Ihren Dienst. Deshalb ist es manchmal notwendig, die Metadaten mit einem sicheren Endpunkt zu veröffentlichen.

Metadatenendpunkte werden in der Regel mithilfe der Standardsicherheitsmechanismen gesichert, die in der Windows Communication Foundation (WCF) zur Sicherung von Anwendungsendpunkten definiert sind. Weitere Informationen finden Sie unter Sicherheitsübersicht.

In diesem Thema sind die Schritte zur Erstellung eines Endpunkts beschrieben, der durch ein Verbunddienst-SSL-Zertifikat gesichert ist, also anders ausgedrückt: die Schritte zur Erstellung eines HTTPS-Endpunkts.

So erstellen Sie einen sicheren HTTPS-GET-Metadatenendpunkt in Code

  1. Konfigurieren Sie einen Anschluss mit einem entsprechenden X.509-Zertifikat. Das Zertifikat muss von einer vertrauenswürdigen Zertifizierungsstelle stammen und den Verwendungszweck „Dienstautorisierung“ aufweisen. Sie müssen das Tool „HttpCfg.exe“ verwenden, um das Zertifikat an den Port anzufügen. Weitere Informationen finden Sie unter Vorgehensweise: Konfigurieren eines Anschlusses mit einem SSL-Zertifikat.

    Wichtig

    Der Betreff des Zertifikats oder das DNS (Domain Name System) muss mit dem Namen des Computers übereinstimmen. Dies ist deshalb wichtig, weil einer der ersten Schritte des HTTPS-Mechanismus darin besteht, zu überprüfen, ob das Zertifikat für denselben URI (Uniform Resource Identifier) ausgestellt wurde wie die Adresse, von der aus es aufgerufen wird.

  2. Erstellen Sie eine neue Instanz der ServiceMetadataBehavior-Klasse.

  3. Legen Sie die HttpsGetEnabled-Eigenschaft der ServiceMetadataBehavior-Klasse auf true fest.

  4. Legen Sie für die HttpsGetUrl-Eigenschaft einen geeigneten URL fest. Beachten Sie, dass die URL mit dem Schema https:// beginnen muss, wenn Sie eine absolute Adresse angeben. Wenn Sie eine relative Adresse angeben, müssen Sie eine HTTPS-Basisadresse für den Diensthost angeben. Wenn diese Eigenschaft nicht festgelegt ist, lautet die Standardadresse "" oder befindet sich direkt an der HTTPS-Basisadresse für den Dienst.

  5. Fügen Sie der Verhaltenssammlung die Instanz hinzu, die von der Behaviors-Eigenschaft der ServiceDescription-Klasse zurückgegeben wird, wie im folgenden Code dargestellt.

    // Create a new metadata behavior object and set its properties to
    // create a secure endpoint.
    ServiceMetadataBehavior sb = new ServiceMetadataBehavior();
    sb.HttpsGetEnabled = true;
    sb.HttpsGetUrl = new Uri("https://myMachineName:8036/myEndpoint");
    myServiceHost.Description.Behaviors.Add(sb);
    
    myServiceHost.Open();
    
    ' Create a new metadata behavior object and set its properties to 
    ' create a secure endpoint. 
    Dim sb As New ServiceMetadataBehavior()
    
    With sb
        .HttpsGetEnabled = True
        .HttpsGetUrl = New Uri("https://myMachineName:8036/myEndpoint")
    End With
    
    With myServiceHost
        .Description.Behaviors.Add(sb)
        .Open()
    End With
    

So erstellen Sie einen sicheren HTTPS-GET-Metadatenendpunkt in der Konfiguration

  1. Fügen Sie ein <behaviors>-Element zum <system.serviceModel>-Element der Konfigurationsdatei für Ihren Dienst hinzu.

  2. Fügen Sie ein <serviceBehaviors>-Element zum <behaviors>-Element hinzu.

  3. Fügen Sie dem <serviceBehaviors>-Element ein <behavior>-Element hinzu.

  4. Legen Sie einen angemessenen Wert für das name-Attribut des <behavior>-Elements fest. Das name-Attribut ist erforderlich. Das nachstehende Beispiel verwendet den Wert mySvcBehavior.

  5. Fügen Sie eine <serviceMetadata>-Instanz zum <behavior>-Element hinzu.

  6. Legen Sie das httpsGetEnabled-Attribut des <serviceMetadata>-Elements auf true fest.

  7. Legen Sie einen angemessenen Wert für das httpsGetUrl-Attribut des <serviceMetadata>-Elements fest. Beachten Sie, dass die URL mit dem Schema https:// beginnen muss, wenn Sie eine absolute Adresse angeben. Wenn Sie eine relative Adresse angeben, müssen Sie eine HTTPS-Basisadresse für den Diensthost angeben. Wenn diese Eigenschaft nicht festgelegt ist, lautet die Standardadresse "" oder befindet sich direkt an der HTTPS-Basisadresse für den Dienst.

  8. Um das Verhalten mit einem Dienst zu verwenden, legen Sie das Attribut behaviorConfiguration des <service>-Elements auf den Wert des name-Attributs des behavior-Elements fest. Der folgende Konfigurationscode zeigt ein vollständiges Beispiel.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
     <system.serviceModel>
      <behaviors>
       <serviceBehaviors>
        <behavior name="mySvcBehavior">
         <serviceMetadata httpsGetEnabled="true"
              httpsGetUrl="https://localhost:8036/calcMetadata" />
        </behavior>
       </serviceBehaviors>
      </behaviors>
     <services>
      <service behaviorConfiguration="mySvcBehavior"
            name="Microsoft.Security.Samples.Calculator">
       <endpoint address="http://localhost:8037/ServiceModelSamples/calculator"
       binding="wsHttpBinding" bindingConfiguration=""
       contract="Microsoft.Security.Samples.ICalculator" />
      </service>
     </services>
    </system.serviceModel>
    </configuration>
    

Beispiel

Im folgenden Beispiel wird eine Instanz einer ServiceHost-Klasse erstellt und ein Endpunkt hinzugefügt. Anschließend erstellt der Code eine Instanz der ServiceMetadataBehavior-Klasse und legt die Eigenschaften zur Erstellung eines sicheren Punkts für den Metadatenaustausch fest.

WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType =
    MessageCredentialType.Windows;

// 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("http://localhost:8037/serviceModelSamples/");

// Create the ServiceHost and add an endpoint.
ServiceHost myServiceHost =
    new ServiceHost(serviceType, baseAddress);
myServiceHost.AddServiceEndpoint
    (contractType, myBinding, "secureCalculator");
// Create a new metadata behavior object and set its properties to
// create a secure endpoint.
ServiceMetadataBehavior sb = new ServiceMetadataBehavior();
sb.HttpsGetEnabled = true;
sb.HttpsGetUrl = new Uri("https://myMachineName:8036/myEndpoint");
myServiceHost.Description.Behaviors.Add(sb);

myServiceHost.Open();
// Use the GetHostEntry method to return the actual machine name.
string machineName = System.Net.Dns.GetHostEntry("").HostName ;
Console.WriteLine("Listening @ {0}:8037/serviceModelSamples/", machineName);
Console.WriteLine("Press Enter to close the service");
Console.ReadLine();
myServiceHost.Close();
Dim myBinding As New WSHttpBinding()
With myBinding.Security
    .Mode = SecurityMode.Message
    .Message.ClientCredentialType = MessageCredentialType.Windows
End With

' Create the Type instances for later use and the URI for 
' the base address.
Dim contractType = GetType(ICalculator)
Dim serviceType = GetType(Calculator)
Dim baseAddress As New Uri("http://localhost:8037/serviceModelSamples/")

' Create the ServiceHost and add an endpoint. 
Dim myServiceHost As New ServiceHost(serviceType, baseAddress)
myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator")

' Create a new metadata behavior object and set its properties to 
' create a secure endpoint. 
Dim sb As New ServiceMetadataBehavior()

With sb
    .HttpsGetEnabled = True
    .HttpsGetUrl = New Uri("https://myMachineName:8036/myEndpoint")
End With

With myServiceHost
    .Description.Behaviors.Add(sb)
    .Open()
End With

' Use the GetHostEntry method to return the actual machine name.
Dim machineName = System.Net.Dns.GetHostEntry("").HostName
Console.WriteLine("Listening @ {0}:8037/serviceModelSamples/", machineName)
Console.WriteLine("Press Enter to close the service")
Console.ReadLine()
myServiceHost.Close()

Kompilieren des Codes

Das Codebeispiel verwendet die folgenden Namespaces:

Siehe auch