Cómo utilizar un nombre de usuario personalizado y un validador de contraseñas

De forma predeterminada, cuando un nombre de usuario y la contraseña se utilizan para la autenticación, Windows Communication Foundation (WCF) utiliza Windows para validar el nombre de usuario y la contraseña. Sin embargo, WCF permite esquemas personalizados de autenticación de nombre de usuario y contraseña, también conocidos como validadores. Para incorporar un nombre de usuario personalizado y un validador de contraseña, cree una clase que derive de UserNamePasswordValidator y, a continuación, configúrela.

Para obtener una aplicación de ejemplo, consulte Validador de contraseña de nombre de usuario.

Para crear un nombre de usuario personalizado y un validador de contraseñas

  1. Cree una clase que derive de UserNamePasswordValidator.

    Public Class CustomUserNameValidator
        Inherits UserNamePasswordValidator
    
    public class CustomUserNameValidator : UserNamePasswordValidator
    {
    
  2. Implemente el esquema personalizado de autenticación invalidando el método Validate.

    No utilice el código en el ejemplo siguiente que invalida el método Validate en un entorno de producción. Reemplace el código con su nombre de usuario personalizado y esquema de validación de contraseña, que podrían implicar la recuperación de los pares de nombre de usuario y contraseña de una base de datos.

    Para devolver errores de autenticación al cliente, inicie una FaultException en el método Validate.

    ' This method validates users. It allows in two users, test1 and test2 
    ' with passwords 1tset and 2tset respectively.
    ' This code is for illustration purposes only and 
    ' must not be used in a production environment because it is not secure.    
    Public Overrides Sub Validate(ByVal userName As String, ByVal password As String)
        If Nothing = userName OrElse Nothing = password Then
            Throw New ArgumentNullException()
        End If
    
        If Not (userName = "test1" AndAlso password = "1tset") AndAlso Not (userName = "test2" AndAlso password = "2tset") Then
            ' This throws an informative fault to the client.
            Throw New FaultException("Unknown Username or Incorrect Password")
            ' When you do not want to throw an infomative fault to the client,
            ' throw the following exception.
            ' Throw New SecurityTokenException("Unknown Username or Incorrect Password")
        End If
    
    End Sub
    
    // This method validates users. It allows in two users, test1 and test2 
    // with passwords 1tset and 2tset respectively.
    // This code is for illustration purposes only and 
    // must not be used in a production environment because it is not secure.    
    public override void Validate(string userName, string password)
    {
        if (null == userName || null == password)
        {
            throw new ArgumentNullException();
        }
    
        if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset"))
        {
            // This throws an informative fault to the client.
            throw new FaultException("Unknown Username or Incorrect Password");
            // When you do not want to throw an infomative fault to the client,
            // throw the following exception.
            // throw new SecurityTokenException("Unknown Username or Incorrect Password");
        }
    }
    

Para configurar un servicio con el fin de utilizar un nombre de usuario personalizado y un validador de contraseñas

  1. Configure un enlace que utilice la seguridad de mensaje sobre cualquier transporte o la seguridad del nivel de transporte sobre HTTP(S).

    Si utiliza la seguridad de mensaje, agregue uno de los enlaces proporcionados por el sistema, como wsHttpBinding Element o customBinding Element, que admita la seguridad de mensaje y el tipo de credencial UserName.

    Cuando use la seguridad del nivel de transporte sobre HTTP(S), agregue el elemento wsHttpBinding Element o <basicHttpBinding>, un elemento <netTcpBinding> o customBinding Element que use HTTP(S) y el esquema de autenticación Basic.

    Aa702565.note(es-es,VS.100).gifNota:
    Si se utiliza .NET Framework versión 3.5 o una versión posterior, puede usarse un validador de nombre de usuario y de contraseña personalizado con la seguridad de mensaje y de transporte. Con .NET Framework 3.0, solo puede utilizarse un validador de nombre de usuario y de contraseña con la seguridad de mensaje.

    Aa702565.Tip(es-es,VS.100).gifSugerencia:
    Para obtener más información sobre el uso de <netTcpBinding> en este contexto, vea <security> of <netTcpBinding>

    1. En el archivo de configuración, en el elemento <system.ServiceModel>, agregue un elemento <bindings>.

    2. Agregue un elemento wsHttpBinding Element o <basicHttpBinding>Para obtener más información sobre a la sección de enlace. WCF la creación de un elemento de enlace Cómo: Especificar un enlace de servicio en la configuración.

    3. Establezca el atributo mode de security element of wsHttpBinding o <security> of <basicHttpBinding>MessageTransport como or, TransportWithMessageCredential, .

    4. Establezca el atributo clientCredentialType de message element of wsHttpBinding o <transport> of <wsHttpBinding>.

      Si utiliza la seguridad de mensaje, establezca el atributo clientCredentialType de message element of wsHttpBinding como UserName.

      Si utiliza la seguridad de nivel de transporte sobre HTTP(S), establezca el atributo clientCredentialType de <transport> of <wsHttpBinding><transport> of <basicHttpBinding>Basic o como .

      Aa702565.note(es-es,VS.100).gifNota:
      Cuando un servicio WCF se hospeda en Internet Information Services (IIS) mediante la seguridad del nivel de transporte, y se establece la propiedad UserNamePasswordValidationMode como Custom, el esquema de autenticación personalizado utiliza un subconjunto de autenticación de Windows. Esto se debe a que en este escenario, IIS realiza la autenticación de Windows antes de que WCF invoque al autenticador personalizado.

    Para Para obtener más información sobre que crea un elemento de enlace WCF, vea Cómo: Especificar un enlace de servicio en la configuración.

    El siguiente ejemplo muestra el código de configuración para el enlace.

    <system.serviceModel> 
      <bindings>
      <wsHttpBinding>
          <binding name="Binding1">
            <security mode="Message">
              <message clientCredentialType="UserName" />
            </security>
          </binding>        
        </wsHttpBinding>
      </bindings>
    </system.serviceModel>
    
  2. Configure un comportamiento que especifique que un nombre de usuario personalizado y el validador de contraseñas se utilizan para validar los pares de nombre de usuario y para los tokens de seguridad UserNameSecurityToken entrantes.

    1. Agregue un elemento secundario al elemento <system.serviceModel><behaviors>, agregue un elemento.

    2. Agregue serviceBehaviors section al elemento <behaviors>.

    3. Agregue un elemento <behavior>name y establezca el atributo en un valor adecuado.

    4. Agregue <serviceCredentials> Element<behavior> al elemento .

    5. Agregue userNameAuthentication element a <serviceCredentials> Element.

    6. Establezca userNamePasswordValidationMode en Custom.

      Aa702565.Important(es-es,VS.100).gif Nota:
      Si no se establece el valor userNamePasswordValidationMode, WCF utiliza la autenticación de Windows en lugar del nombre de usuario personalizado y validador de la contraseña.

    7. Establezca customUserNamePasswordValidatorType en el tipo que representa su nombre de usuario personalizado y el validador de la contraseña.

    El ejemplo siguiente muestra el fragmento <serviceCredentials> en este punto.

    <serviceCredentials>
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.CalculatorService.CustomUserNameValidator, service" />
    </serviceCredentials>
    

Ejemplo

El ejemplo de código siguiente muestra cómo crear un nombre de usuario personalizado y el validador de la contraseña. No utilice el código que invalida el método Validate en un entorno de producción. Reemplace el código con su nombre de usuario personalizado y esquema de validación de contraseña, que podrían implicar la recuperación de los pares de nombre de usuario y contraseña de una base de datos.

Imports System

Imports System.IdentityModel.Selectors
Imports System.IdentityModel.Tokens

Imports System.Security.Principal

Imports System.ServiceModel

    

    
    ...
    
    

        Public Class CustomUserNameValidator
        Inherits UserNamePasswordValidator
        ' This method validates users. It allows in two users, test1 and test2 
        ' with passwords 1tset and 2tset respectively.
        ' This code is for illustration purposes only and 
        ' must not be used in a production environment because it is not secure.    
        Public Overrides Sub Validate(ByVal userName As String, ByVal password As String)
            If Nothing = userName OrElse Nothing = password Then
                Throw New ArgumentNullException()
            End If

            If Not (userName = "test1" AndAlso password = "1tset") AndAlso Not (userName = "test2" AndAlso password = "2tset") Then
                ' This throws an informative fault to the client.
                Throw New FaultException("Unknown Username or Incorrect Password")
                ' When you do not want to throw an infomative fault to the client,
                ' throw the following exception.
                ' Throw New SecurityTokenException("Unknown Username or Incorrect Password")
            End If

        End Sub
    End Class
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

using System.Security.Principal;

using System.ServiceModel;

    

    
    ...
    
    

    
        public class CustomUserNameValidator : UserNamePasswordValidator
        {
            // This method validates users. It allows in two users, test1 and test2 
            // with passwords 1tset and 2tset respectively.
            // This code is for illustration purposes only and 
            // must not be used in a production environment because it is not secure.   
            public override void Validate(string userName, string password)
            {
                if (null == userName || null == password)
                {
                    throw new ArgumentNullException();
                }

                if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset"))
                {
                    // This throws an informative fault to the client.
                    throw new FaultException("Unknown Username or Incorrect Password");
                    // When you do not want to throw an infomative fault to the client,
                    // throw the following exception.
                    // throw new SecurityTokenException("Unknown Username or Incorrect Password");
                }
            }
        }

Vea también

Tareas

Cómo: Utilizar el proveedor de pertenencia de ASP.NET

Referencia

UserNamePasswordValidator

Otros recursos

Autenticación