Seguridad de los mensajes con un cliente de nombres de usuario

La ilustración siguiente muestra un servicio y cliente de Windows Communication Foundation (WCF) protegidos mediante seguridad del nivel de mensaje. La autenticación del servicio se realiza mediante un certificado X.509. El cliente se autentica utilizando un nombre de usuario y contraseña.

Para obtener una aplicación de ejemplo, consulte Nombre de usuario de seguridad de mensaje.

Seguridad de mensajes mediante la autenticación de nombre de usuario

Característica Descripción

Modo de seguridad

Mensaje

Interoperabilidad

Solo Windows Communication Foundation (WCF)

Autenticación (servidor)

La negociación inicial requiere autenticación de servidor

Autenticación (cliente)

Nombre de usuario/contraseña

Integridad

Sí, mediante el contexto de seguridad compartido

Confidencialidad

Sí, mediante el contexto de seguridad compartido

Transporte

HTTP

Enlace

WSHttpBinding

Servicio

El código y la configuración siguientes están diseñados para ejecutarse de forma independiente. Siga uno de los procedimientos siguientes:

  • Cree un servicio independiente mediante el código sin configuración.

  • Cree un servicio con la configuración proporcionada, pero sin definir ningún extremo.

Código

El código siguiente muestra cómo crear un extremo de servicio que utiliza la seguridad del mensaje.

' Create the binding.
Dim binding As New WSHttpBinding()
binding.Security.Mode = SecurityMode.Message
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName

' Create the URI for the endpoint.
Dim httpUri As New Uri("https://localhost/Calculator")

' Create the service host.
Dim myServiceHost As New ServiceHost(GetType(ServiceModel.Calculator), httpUri)
myServiceHost.AddServiceEndpoint(GetType(ICalculator), binding, "")

' Specify a certificate to authenticate the service.
myServiceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, _
StoreName.My, X509FindType.FindBySubjectName, "Contoso.com")

myServiceHost.Open()
Console.WriteLine("Listening...")
Console.ReadLine()

' Close the service. 
myServiceHost.Close()
// Create the binding.
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType =
     MessageCredentialType.UserName;

// Create the URI for the endpoint.
Uri httpUri = new Uri("https://localhost/Calculator");

// Create the service host.
ServiceHost myServiceHost =
    new ServiceHost(typeof(Calculator), httpUri);
myServiceHost.AddServiceEndpoint(typeof(ICalculator), binding, "");

// Specify a certificate to authenticate the service.
myServiceHost.Credentials.ServiceCertificate.
    SetCertificate(StoreLocation.LocalMachine,
    StoreName.My,
    X509FindType.FindBySubjectName,
    "Contoso.com");

myServiceHost.Open();
Console.WriteLine("Listening...");
Console.ReadLine();

// Close the service. 
myServiceHost.Close();

Configuración

La siguiente configuración se puede usar en lugar del código.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceCredentialsBehavior">
          <serviceCredentials>
            <serviceCertificate findValue="Contoso.com" 
                                storeLocation="LocalMachine"
                                storeName="My"   
                                x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="ServiceCredentialsBehavior"
               name="ServiceModel.Calculator">
        <endpoint address="https://localhost/Calculator"
                  binding="wsHttpBinding"
                  bindingConfiguration="MessageAndUserName"
                  name="SecuredByTransportEndpoint"
                  contract="ServiceModel.ICalculator" />
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="MessageAndUserName">
          <security mode="Message">            
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client />
  </system.serviceModel>
</configuration>

Client

Código

El siguiente código crea el cliente. El enlace es para la seguridad del modo de mensaje y el tipo de credencial de cliente está establecido en UserName. El nombre de usuario y la contraseña solo se pueden especificar mediante código (no es configurable). El código para devolver el nombre de usuario y la contraseña no se muestra aquí porque se debe hacer en el nivel de la aplicación. Por ejemplo, utilice un cuadro de diálogo de Window Forms para solicitar los datos al usuario.

' Create the binding.
Dim myBinding As New WSHttpBinding()
myBinding.Security.Mode = SecurityMode.Message
myBinding.Security.Message.ClientCredentialType = _
   MessageCredentialType.UserName

' Create the endpoint address. 
Dim ea As New EndpointAddress("http://machineName/Calculator")

' Create the client. 
Dim cc As New CalculatorClient(myBinding, ea)

' Set the user name and password. The code to 
' return the user name and password is not shown here. Use
' an interface to query the user for the information.
cc.ClientCredentials.UserName.UserName = ReturnUsername()
cc.ClientCredentials.UserName.Password = ReturnPassword()

' 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.UserName;

// Create the endpoint address. 
EndpointAddress ea = new
    EndpointAddress("http://machineName/Calculator");

// Create the client. 
CalculatorClient cc =
    new CalculatorClient(myBinding, ea);

// Set the user name and password. The code to 
// return the user name and password is not shown here. Use
// an interface to query the user for the information.
cc.ClientCredentials.UserName.UserName = ReturnUsername();
cc.ClientCredentials.UserName.Password = ReturnPassword();

// Begin using the client.
try
{
    cc.Open();
    Console.WriteLine(cc.Add(200, 1111));
    Console.ReadLine();

    // Close the client.
    cc.Close();
}

Configuración

El siguiente código configura el cliente. El enlace es para la seguridad del modo de mensaje y el tipo de credencial de cliente está establecido en UserName. El nombre de usuario y la contraseña solo se pueden especificar mediante código (no es configurable).

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_ICalculator" >
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://machineName/Calculator" 
                binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_ICalculator" 
                contract="ICalculator"
                name="WSHttpBinding_ICalculator">
        <identity>
          <dns value ="Contoso.com" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

Vea también

Tareas

Nombre de usuario de seguridad de mensaje

Conceptos

Información general sobre seguridad
Identidad del servicio y autenticación

Otros recursos

<identity>
Modelo de seguridad para Windows Server App Fabric