Programación de la seguridad de WCFProgramming WCF Security

En este tema se describen las tareas de programación fundamentales que se usan para crear una aplicación Secure Windows Communication Foundation (WCF).This topic describes the fundamental programming tasks used to create a secure Windows Communication Foundation (WCF) application. En este tema solo se trata la autenticación, la confidencialidad y la integridad, que se conocen colectivamente como seguridad de transferencia.This topic covers only authentication, confidentiality, and integrity, collectively known as transfer security. En este tema no se trata la autorización (el control de acceso a los recursos o servicios). para obtener información sobre la autorización, vea autorización.This topic does not cover authorization (the control of access to resources or services); for information on authorization, see Authorization.

Nota

Para obtener una introducción valiosa a los conceptos de seguridad, especialmente en relación con WCF, vea el conjunto de tutoriales de patrones y prácticas de MSDN en escenarios, patrones e instrucciones de implementación para 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.

La programación de la seguridad de WCF se basa en tres pasos que establecen lo siguiente: el modo de seguridad, un tipo de credencial de cliente y los valores de credenciales.Programming WCF security is based on three steps setting the following: the security mode, a client credential type, and the credential values. Puede realizar estos pasos mediante código o configuración.You can perform these steps either through code or configuration.

Establecimiento del modo de seguridadSetting the Security Mode

A continuación se explican los pasos generales para programar con el modo de seguridad en WCF:The following explains the general steps for programming with the security mode in WCF:

  1. Seleccione uno de los enlaces predefinidos adecuado a sus requisitos de aplicación.Select one of the predefined bindings appropriate to your application requirements. Para obtener una lista de las opciones de enlace, vea enlaces proporcionadospor el sistema.For a list of the binding choices, see System-Provided Bindings. De forma predeterminada, prácticamente todos los enlaces tienen la seguridad habilitada.By default, nearly every binding has security enabled. La única excepción es la BasicHttpBinding clase (mediante la configuración, el <basicHttpBinding >).The one exception is the BasicHttpBinding class (using configuration, the <basicHttpBinding>).

    El enlace que seleccione determina el transporte.The binding you select determines the transport. Por ejemplo, WSHttpBinding utiliza HTTP como el transporte; NetTcpBinding utiliza TCP.For example, WSHttpBinding uses HTTP as the transport; NetTcpBinding uses TCP.

  2. Seleccione uno de los modos de seguridad para el enlace.Select one of the security modes for the binding. Tenga en cuenta que el enlace que seleccione determinará las opciones de modo disponibles.Note that the binding you select determines the available mode choices. Por ejemplo, WSDualHttpBinding no permite la seguridad de transporte (no es una opción).For example, the WSDualHttpBinding does not allow transport security (it is not an option). De igual forma, ni MsmqIntegrationBinding ni NetNamedPipeBinding permiten el modo de seguridad.Similarly, neither the MsmqIntegrationBinding nor the NetNamedPipeBinding allows message security.

    Dispone de tres opciones:You have three choices:

    1. Transport

      La seguridad de transporte depende del mecanismo que use el enlace que ha seleccionado.Transport security depends on the mechanism that the binding you have selected uses. Por ejemplo, si utiliza WSHttpBinding, el mecanismo de seguridad es Secure Sockets Layer (SSL) (también es el mecanismo para el protocolo HTTPS).For example, if you are using WSHttpBinding then the security mechanism is Secure Sockets Layer (SSL) (also the mechanism for the HTTPS protocol). Generalmente hablando, la principal ventaja de la seguridad de transporte es que proporciona un buen rendimiento independientemente del transporte que esté utilizando.Generally speaking, the main advantage of transport security is that it delivers good throughput no matter which transport you are using. No obstante, tiene dos limitaciones: la primera es que el mecanismo de transporte dicta el tipo de credencial utilizado para autenticar a un usuario.However, it does have two limitations: The first is that the transport mechanism dictates the credential type used to authenticate a user. Ésta es una desventaja solo si un servicio necesita interoperar con otros servicios que exigen tipos diferentes de credenciales.This is a drawback only if a service needs to interoperate with other services that demand different types of credentials. La segunda es que, puesto que la seguridad no se aplica en el nivel de mensaje, la seguridad se implementa salto por salto en lugar de de extremo a extremo.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. Esta última limitación es un problema solo si la ruta de mensajes entre el cliente y el servicio incluye intermediarios.This latter limitation is an issue only if the message path between client and service includes intermediaries. Para obtener más información acerca del transporte que se va a usar, consulte elección de un transporte.For more information about which transport to use, see Choosing a Transport. Para obtener más información sobre el uso de la seguridad de transporte, vea información generalsobre la seguridad de transporte.For more information about using transport security, see Transport Security Overview.

    2. Message

      El modo de seguridad significa que cada mensaje incluye los encabezados y datos necesarios para mantener el mensaje protegido.Message security means that every message includes the necessary headers and data to keep the message secure. Dado que la composición de los encabezados varía, puede incluir cualquier número de credenciales.Because the composition of the headers varies, you can include any number of credentials. Este es un factor a tener en cuenta si está interoperando con otros servicios que exigen un tipo de credencial concreto que un mecanismo de transporte no puede proporcionar o si el mensaje se debe utilizar con más de un servicio, donde cada servicio exige un tipo de credencial diferente.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.

      Para obtener más información, vea seguridad de mensajes.For more information, see Message Security.

    3. TransportWithMessageCredential

      Esta opción utiliza el nivel de transporte para proteger la transferencia del mensaje, mientras que cada mensaje incluye las credenciales enriquecidas que otros servicios necesitan.This choice uses the transport layer to secure the message transfer, while every message includes the rich credentials other services need. Esto combina la ventaja de rendimiento de la seguridad de transporte con la ventaja de las credenciales enriquecidas de la seguridad de mensaje.This combines the performance advantage of transport security with the rich credentials advantage of message security. Esto está disponible con los siguientes enlaces: BasicHttpBinding, WSFederationHttpBinding, NetPeerTcpBinding y WSHttpBinding.This is available with the following bindings: BasicHttpBinding, WSFederationHttpBinding, NetPeerTcpBinding, and WSHttpBinding.

  3. Si decide utilizar la seguridad de transporte para HTTP (en otras palabras, HTTPS), debe configurar también el host con un certificado SSL y habilitar SSL en un puerto.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. Para obtener más información, vea seguridad de transporte http.For more information, see HTTP Transport Security.

  4. Si está utilizando el WSHttpBinding y no necesita establecer una sesión segura, establezca la propiedad EstablishSecurityContext en false.If you are using the WSHttpBinding and do not need to establish a secure session, set the EstablishSecurityContext property to false.

    Una sesión segura se produce cuando un cliente y servicio crean un canal mediante una clave simétrica (tanto el cliente como el servidor usan la misma clave durante la duración de una conversación, hasta que se cierre el diálogo).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).

Establecimiento del tipo de credencial de clienteSetting the Client Credential Type

Seleccione según corresponda un tipo de credencial de cliente.Select a client credential type as appropriate. Para obtener más información, consulte seleccionar un tipo de credencial.For more information, see Selecting a Credential Type. Los siguientes tipos de credencial de cliente están disponibles:The following client credential types are available:

  • Windows

  • Certificate

  • Digest

  • Basic

  • UserName

  • NTLM

  • IssuedToken

Dependiendo de cómo establezca el modo, deberá establecer el tipo de credencial.Depending on how you set the mode, you must set the credential type. Por ejemplo, si ha seleccionado el wsHttpBinding, y ha establecido el modo en "Mensaje", también puede establecer el atributo clientCredentialType del elemento Message en uno de los valores siguientes: None, Windows, UserName, Certificate y IssuedToken, como se muestra en el ejemplo de configuración siguiente.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>  

O bien, en el código: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

Establecimiento de valores de credenciales de servicioSetting Service Credential Values

Cuando selecciona un tipo de credencial de cliente, debe establecer las credenciales reales que el servicio y el cliente han de utilizar.Once you select a client credential type, you must set the actual credentials for the service and client to use. En el servicio, las credenciales se establecen utilizando la clase ServiceCredentials y se devuelven mediante la propiedad Credentials de la clase ServiceHostBase.On the service, credentials are set using the ServiceCredentials class and returned by the Credentials property of the ServiceHostBase class. El enlace en uso implica el tipo de credencial de servicio, el modo de seguridad elegido y el tipo de la credencial de cliente.The binding in use implies the service credential type, the security mode chosen, and the type of the client credential. El código siguiente establece un certificado para una credencial de servicio.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 communication error occurred: {0}", ce.Message);
    Console.WriteLine();
}
catch (System.Exception exc)
{
    Console.WriteLine("An unforeseen 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 communication error occurred: {0}", ce.Message)
    Console.WriteLine()
Catch exc As System.Exception
    Console.WriteLine("An unforeseen error occurred: {0}", exc.Message)
    Console.ReadLine()
End Try

Establecimiento de los valores de credencial de clienteSetting Client Credential Values

En el cliente, establezca valores de credencial de cliente mediante la clase ClientCredentials y devueltos por la propiedad ClientCredentials de la clase ClientBase<TChannel>.On the client, set client credential values using the ClientCredentials class and returned by the ClientCredentials property of the ClientBase<TChannel> class. El código siguiente establece un certificado como una credencial en un cliente utilizando el protocolo TCP.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()

Vea tambiénSee also