Programmieren der WCF-SicherheitProgramming WCF Security

Dieses Thema beschreibt die grundlegenden Programmierungsaufgaben zum Erstellen einer sicheren Windows Communication Foundation (WCF)-Anwendung verwendet.This topic describes the fundamental programming tasks used to create a secure Windows Communication Foundation (WCF) application. Dieses Thema behandelt nur Authentifizierung, Vertraulichkeit und Integrität, Oberbegriff übertragungssicherheit.This topic covers only authentication, confidentiality, and integrity, collectively known as transfer security. Autorisierung (Kontrolle des Zugriffs auf Ressourcen oder Dienste); behandelt in diesem Thema nicht. Weitere Informationen zur Autorisierung finden Sie unter Autorisierung.This topic does not cover authorization (the control of access to resources or services); for information on authorization, see Authorization.

Hinweis

Eine wertvolle Einführung in Schlüsselbegriffe der Sicherheit, insbesondere hinsichtlich WCF, finden Sie unter den Satz von Muster und Praktiken Lernprogramme auf MSDN unter Szenarien, Muster und Implementation Guidance für Web Services Enhancements (WSE) 3.0.For a valuable introduction to security concepts, especially in regard to WCF, see the set of patterns and practices tutorials on MSDN at Scenarios, Patterns, and Implementation Guidance for Web Services Enhancements (WSE) 3.0.

Programmieren der WCF-Sicherheit basiert auf drei Schritten, mit denen Folgendes: der Sicherheitsmodus, einen Clientanmeldeinformationstyp und anmeldeinformationswerte.Programming WCF security is based on three steps setting the following: the security mode, a client credential type, and the credential values. Sie können diese Schritte durch Code oder die Konfiguration durchführen.You can perform these steps either through code or configuration.

Festlegen des SicherheitsmodusSetting the Security Mode

Im nachfolgenden Abschnitt werden die allgemeinen Schritte für die Programmierung mit dem Sicherheitsmodus in WCF:The following explains the general steps for programming with the security mode in WCF:

  1. Wählen Sie eine der vordefinierten Bindungen, die den Anwendungsanforderungen entsprechen.Select one of the predefined bindings appropriate to your application requirements. Eine Übersicht über die bindungsauswahlmöglichkeiten finden Sie unter sicherheitsbindungsarten Bindungen.For a list of the binding choices, see System-Provided Bindings. Standardmäßig ist beinahe jede Bindung sicherheitsaktiviert.By default, nearly every binding has security enabled. Die einzige Ausnahme ist die BasicHttpBinding Klasse (mit der Konfiguration kann die <BasicHttpBinding >).The one exception is the BasicHttpBinding class (using configuration, the <basicHttpBinding>).

    Durch die von Ihnen ausgewählte Bindung bestimmen Sie auch den Transport.The binding you select determines the transport. WSHttpBinding verwendet beispielsweise HTTP als Transportmethode, NetTcpBinding verwendet TCP.For example, WSHttpBinding uses HTTP as the transport; NetTcpBinding uses TCP.

  2. Wählen Sie einen der Sicherheitsmodi für die Bindung aus.Select one of the security modes for the binding. Beachten Sie, dass die von Ihnen ausgewählte Bindung auch die Verfügbarkeit der Modi beeinflusst.Note that the binding you select determines the available mode choices. Die WSDualHttpBinding ermöglicht beispielsweise keine Transportsicherheit. (Sie steht nicht als Option zur Verfügung.)For example, the WSDualHttpBinding does not allow transport security (it is not an option). Auf ähnliche Weise ermöglichen weder MsmqIntegrationBinding noch NetNamedPipeBinding die Nachrichtensicherheit.Similarly, neither the MsmqIntegrationBinding nor the NetNamedPipeBinding allows message security.

    Sie haben drei Möglichkeiten:You have three choices:

    1. Transport

      Die Transportsicherheit ist vom Mechanismus abhängig, den die ausgewählte Bindung verwendet.Transport security depends on the mechanism that the binding you have selected uses. Wenn Sie beispielsweise WSHttpBinding verwenden, wird als Sicherheitsmechanismus Secure Sockets Layer (SSL) verwendet, was auch der Mechanismus für das HTTPS-Protokoll ist.For example, if you are using WSHttpBinding then the security mechanism is Secure Sockets Layer (SSL) (also the mechanism for the HTTPS protocol). Der Hauptvorteil der Transportsicherheit besteht im Allgemeinen darin, dass sie unabhängig von der Transportmethode einen guten Durchsatz ermöglicht.Generally speaking, the main advantage of transport security is that it delivers good throughput no matter which transport you are using. Es gibt jedoch zwei Einschränkungen: Der Transportmechanismus bestimmt den Anmeldeinformationstyp, der zum Authentifizieren eines Benutzers verwendet wird.However, it does have two limitations: The first is that the transport mechanism dictates the credential type used to authenticate a user. Dies ist jedoch nur dann von Nachteil, wenn ein Dienst mit anderen Diensten zusammenarbeiten muss, für die unterschiedliche Anmeldeinformationstypen notwendig sind.This is a drawback only if a service needs to interoperate with other services that demand different types of credentials. Darüber hinaus wird die Sicherheit nicht auf Nachrichtenebene angewendet, vielmehr wird die Sicherheit per Hop-by-Hop-Methode anstelle einer End-to-End-Methode implementiert.The second is that, because the security is not applied at the message level, security is implemented in a hop-by-hop manner rather than end-to-end. Diese zweite Einschränkung ist nur dann ein Problem, wenn der Nachrichtenpfad zwischen Client und Dienst Vermittler umfasst.This latter limitation is an issue only if the message path between client and service includes intermediaries. Weitere Informationen zu der Transporttyp, finden Sie unter Wählen eines Transports.For more information about which transport to use, see Choosing a Transport. Weitere Informationen zur Verwendung von transportsicherheit finden Sie unter Transport Sicherheitsübersicht.For more information about using transport security, see Transport Security Overview.

    2. Message

      Nachrichtensicherheit bedeutet, dass jede Nachricht die notwendigen Header und Daten enthält, um die Nachricht zu sichern.Message security means that every message includes the necessary headers and data to keep the message secure. Da die Struktur der Header unterschiedlich ist, können Sie beliebig viele Anmeldeinformationen umfassen.Because the composition of the headers varies, you can include any number of credentials. Dies spielt eine Rolle, wenn Sie mit anderen Diensten zusammenarbeiten, die einen bestimmten Anmeldeinformationstyp erfordern, den ein Transportmechanismus nicht bereitstellen kann, oder wenn die Nachricht mit mehr als einem Dienst verwendet werden muss, wobei jeder Dienst einen unterschiedlichen Anmeldeinformationstyp erfordert.This becomes a factor if you are interoperating with other services that demand a specific credential type that a transport mechanism can't supply, or if the message must be used with more than one service, where each service demands a different credential type.

      Weitere Informationen finden Sie unter Nachrichtensicherheit.For more information, see Message Security.

    3. TransportWithMessageCredential

      Diese Auswahl verwendet die Transportschicht, um die Nachrichtenübertragung zu sichern, während jede Nachricht die komplexen Anmeldeinformationen enthält, die andere Dienste benötigen.This choice uses the transport layer to secure the message transfer, while every message includes the rich credentials other services need. Dadurch wird der Leistungsvorteil der Transportsicherheit mit dem Vorteil komplexer Anmeldeinformationen der Nachrichtensicherheit kombiniert.This combines the performance advantage of transport security with the rich credentials advantage of message security. Dies ist mit den folgenden Bindungen verfügbar: BasicHttpBinding, WSFederationHttpBinding, NetPeerTcpBinding und WSHttpBinding.This is available with the following bindings: BasicHttpBinding, WSFederationHttpBinding, NetPeerTcpBinding, and WSHttpBinding.

  3. Wenn Sie für HTTP eine Transportsicherheit verwenden möchten (d. h. HTTPS), müssen Sie auch den Host mit einem SSL-Zertifikat konfigurieren und SSL auf einem Port aktivieren.If you decide to use transport security for HTTP (in other words, HTTPS), you must also configure the host with an SSL certificate and enable SSL on a port. Weitere Informationen finden Sie unter HTTP-Transportsicherheit.For more information, see HTTP Transport Security.

  4. Wenn Sie WSHttpBinding verwenden und keine sichere Sitzung einrichten müssen, legen Sie für die EstablishSecurityContext-Eigenschaft den Wert false fest.If you are using the WSHttpBinding and do not need to establish a secure session, set the EstablishSecurityContext property to false.

    Eine sichere Sitzung entsteht, wenn ein Client und ein Dienst einen Kanal mithilfe eines symmetrischen Schlüssels erstellen (sowohl Client als auch Server verwenden den gleichen Schlüssel für die Dauer einer Konversation und bis der Dialog geschlossen wird).A secure session occurs when a client and service create a channel using a symmetric key (both client and server use the same key for the length of a conversation, until the dialog is closed).

Festlegen des ClientanmeldeinformationstypsSetting the Client Credential Type

Wählen Sie wie erforderlich einen Clientanmeldeinformationstyp aus.Select a client credential type as appropriate. Weitere Informationen finden Sie unter Auswählen eines Anmeldeinformationentyps.For more information, see Selecting a Credential Type. Die folgenden Clientanmeldeinformationstypen sind verfügbar:The following client credential types are available:

  • Windows

  • Certificate

  • Digest

  • Basic

  • UserName

  • NTLM

  • IssuedToken

Die Art und Weise, wie Sie den Modus festlegen, bestimmt auch die Festlegung des Anmeldeinformationstyps.Depending on how you set the mode, you must set the credential type. Wenn Sie beispielsweise wsHttpBinding ausgewählt haben und als Modus "Message" festgelegt haben, können Sie auch das clientCredentialType-Attribut des Nachrichtenelements auf einen der folgenden Werte festlegen: None, Windows, UserName, Certificate und IssuedToken, wie im folgenden Konfigurationsbeispiel gezeigt wird.For example, if you have selected the wsHttpBinding, and have set the mode to "Message," then you can also set the clientCredentialType attribute of the Message element to one of the following values: None, Windows, UserName, Certificate, and IssuedToken, as shown in the following configuration example.

<system.serviceModel>  
<bindings>  
  <wsHttpBinding>  
    <binding name="myBinding">  
      <security mode="Message"/>  
      <message clientCredentialType="Windows"/>  
    </binding>  
</bindings>  
</system.serviceModel>  

Oder in Code:Or in code:

WSHttpBinding b = new WSHttpBinding();
b.Name = "myBinding";
b.Security.Mode = SecurityMode.Message;
b.Security.Message.ClientCredentialType=MessageCredentialType.Windows;
Dim b As New WSHttpBinding()
b.Name = "myBinding"
b.Security.Mode = SecurityMode.Message
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows

Festlegen von DienstanmeldeinformationswertenSetting Service Credential Values

Nachdem Sie einen Dienstanmeldeinformationstyp ausgewählt haben, müssen Sie die tatsächlichen Anmeldeinformationen für den zu verwendenden Dienst und Client festlegen.Once you select a client credential type, you must set the actual credentials for the service and client to use. Für den Dienst werden die Anmeldeinformationen mit der ServiceCredentials-Klasse festgelegt und von der Credentials-Eigenschaft der ServiceHostBase-Klasse zurückgegeben.On the service, credentials are set using the ServiceCredentials class and returned by the Credentials property of the ServiceHostBase class. Die verwendete Bindung gibt den Dienstanmeldeinformationstyp, den ausgewählten Sicherheitsmodus und den Typ der Clientanmeldeinformationen an.The binding in use implies the service credential type, the security mode chosen, and the type of the client credential. Mit dem folgenden Code wird ein Zertifikat für die Dienstanmeldeinformationen festgelegt:The following code sets a certificate for a service credential.

// Create the binding for an endpoint.
NetTcpBinding b = new NetTcpBinding();
b.Security.Mode = SecurityMode.Message;

// Create the ServiceHost for a calculator.
Uri baseUri = new Uri("net.tcp://MachineName/tcpBase");
Uri[] baseAddresses = new Uri[] { baseUri };
ServiceHost sh = new ServiceHost(typeof(Calculator), baseAddresses);

// Add an endpoint using the binding and a new address.
Type c = typeof(ICalculator);
sh.AddServiceEndpoint(c, b, "MyEndpoint");

// Set a certificate as the credential for the service.
sh.Credentials.ServiceCertificate.SetCertificate(
    StoreLocation.LocalMachine,
    StoreName.My,
    X509FindType.FindBySubjectName,
    "client.com");
try
{
    sh.Open();
    Console.WriteLine("Listening....");
    Console.ReadLine();
    sh.Close();
}
catch (CommunicationException ce)
{
    Console.WriteLine("A commmunication error occurred: {0}", ce.Message);
    Console.WriteLine();
}
catch (System.Exception exc)
{
    Console.WriteLine("An unforseen error occurred: {0}", exc.Message);
    Console.ReadLine();
}
' Create the binding for an endpoint.
Dim b As New NetTcpBinding()
b.Security.Mode = SecurityMode.Message

' Create the ServiceHost for a calculator.
Dim baseUri As New Uri("net.tcp://MachineName/tcpBase")
Dim baseAddresses() As Uri = {baseUri}
Dim sh As New ServiceHost(GetType(Calculator), baseAddresses)

' Add an endpoint using the binding and a new address.
Dim c As Type = GetType(ICalculator)
sh.AddServiceEndpoint(c, b, "MyEndpoint")

' Set a certificate as the credential for the service.
sh.Credentials.ServiceCertificate.SetCertificate( _
                StoreLocation.LocalMachine, _
                StoreName.My, _
                X509FindType.FindBySubjectName, _
                "contoso.com")
Try
    sh.Open()
    Console.WriteLine("Listening....")
    Console.ReadLine()
    sh.Close()
Catch ce As CommunicationException
    Console.WriteLine("A commmunication error occurred: {0}", ce.Message)
    Console.WriteLine()
Catch exc As System.Exception
    Console.WriteLine("An unforseen error occurred: {0}", exc.Message)
    Console.ReadLine()
End Try

Festlegen der Werte der ClientanmeldeinformationenSetting Client Credential Values

Für den Client werden die Clientanmeldeinformationswerte mit der ClientCredentials-Klasse festgelegt und von der ClientCredentials-Eigenschaft der ClientBase<TChannel>-Klasse zurückgegeben.On the client, set client credential values using the ClientCredentials class and returned by the ClientCredentials property of the ClientBase<TChannel> class. Mit dem folgenden Code wird ein Zertifikat als Anmeldeinformationen auf einem Client mit dem TCP-Protokoll festgelegt.The following code sets a certificate as a credential on a client using the TCP protocol.

// Create a NetTcpBinding and set its security properties. The
// security mode is Message, and the client must be authenticated with
// Windows. Therefore the client must be on the same Windows domain.
NetTcpBinding b = new NetTcpBinding();
b.Security.Mode = SecurityMode.Message;
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

// Set a Type variable for use when constructing the endpoint.
Type c = typeof(ICalculator);

// Create a base address for the service.
Uri tcpBaseAddress =
    new Uri("net.tcp://machineName.Domain.Contoso.com:8036/serviceName");
// The base address is in an array of URI objects.
Uri[] baseAddresses = new Uri[] { tcpBaseAddress };
// Create the ServiceHost with type and base addresses.
ServiceHost sh = new ServiceHost(typeof(CalculatorClient), baseAddresses);

// Add an endpoint to the service using the service type and binding.
sh.AddServiceEndpoint(c, b, "");
sh.Open();
string address = sh.Description.Endpoints[0].ListenUri.AbsoluteUri;
Console.WriteLine("Listening @ {0}", address);
Console.WriteLine("Press enter to close the service");
Console.ReadLine();
' Create a NetTcpBinding and set its security properties. The
' security mode is Message, and the client must be authenticated with
' Windows. Therefore the client must be on the same Windows domain.
Dim b As New NetTcpBinding()
b.Security.Mode = SecurityMode.Message
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows

' Set a Type variable for use when constructing the endpoint.
Dim c As Type = GetType(ICalculator)

' Create a base address for the service.
Dim tcpBaseAddress As New Uri("net.tcp://machineName.Domain.Contoso.com:8036/serviceName")
' The base address is in an array of URI objects.
Dim baseAddresses() As Uri = {tcpBaseAddress}
' Create the ServiceHost with type and base addresses.
Dim sh As New ServiceHost(GetType(CalculatorClient), baseAddresses)

' Add an endpoint to the service using the service type and binding.
sh.AddServiceEndpoint(c, b, "")
sh.Open()
Dim address As String = sh.Description.Endpoints(0).ListenUri.AbsoluteUri
Console.WriteLine("Listening @ {0}", address)
Console.WriteLine("Press enter to close the service")
Console.ReadLine()

Siehe auchSee Also

Einfache WCF-ProgrammierungBasic WCF Programming
Häufige SicherheitsszenarienCommon Security Scenarios