Partekatu bidez


Proveedor de tokens

En este ejemplo se muestra cómo implementar un proveedor de tokens personalizado. Se usa un proveedor de tokens en Windows Communication Foundation (WCF) para proporcionar credenciales a la infraestructura de seguridad. El proveedor de tokens en general examina el destino y emite las credenciales adecuadas para que la infraestructura de seguridad pueda proteger el mensaje. WCF incluye el proveedor de tokens del Administrador de credenciales predeterminado. WCF también viene con un proveedor de tokens de CardSpace. Los proveedores de tokens personalizados son útiles en los casos siguientes:

  • Si tiene un almacén de credenciales con el que estos proveedores de tokens no pueden funcionar.

  • Si desea proporcionar su propio mecanismo personalizado para transformar las credenciales desde el punto en que el usuario proporciona los detalles a cuando el marco de cliente WCF usa las credenciales.

  • Si está creando un token personalizado.

En este ejemplo se muestra cómo crear un proveedor de tokens personalizado que transforma la entrada del usuario en un formato diferente.

En resumen, este ejemplo muestra lo siguiente:

  • Cómo se puede autenticar un cliente mediante un par de nombre de usuario y contraseña.

  • Cómo se puede configurar un cliente con un proveedor de tokens personalizado.

  • Cómo el servidor puede validar las credenciales de cliente mediante una contraseña con un personalizado UserNamePasswordValidator que valida que el nombre de usuario y la contraseña coinciden.

  • Cómo el cliente autentica al servidor utilizando el certificado X.509 del servidor.

En este ejemplo también se muestra cómo se puede acceder a la identidad del autor de la llamada después del proceso de autenticación de tokens personalizado.

El servicio expone un único punto de conexión para comunicarse con el servicio, definido mediante el archivo de configuración de App.config. El punto de conexión está compuesto por una dirección, un enlace y un contrato. El enlace se configura con un estándar wsHttpBinding, que usa la seguridad del mensaje de forma predeterminada. En este ejemplo se establece el estándar wsHttpBinding para usar la autenticación de nombre de usuario de cliente. El servicio también configura el certificado de servicio mediante el comportamiento serviceCredentials. El comportamiento de serviceCredentials permite configurar un certificado de servicio. Un cliente usa un certificado de servicio para autenticar el servicio y proporcionar protección de mensajes. La siguiente configuración hace referencia al certificado localhost instalado durante la configuración de ejemplo, tal como se describe en las instrucciones de instalación siguientes.

<system.serviceModel>
    <services>
      <service
          name="Microsoft.ServiceModel.Samples.CalculatorService"
          behaviorConfiguration="CalculatorServiceBehavior">
        <host>
          <baseAddresses>
            <!-- configure base address provided by host -->
            <add baseAddress ="http://localhost:8000/servicemodelsamples/service"/>
          </baseAddresses>
        </host>
        <!-- use base address provided by host -->
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="Binding1"
                  contract="Microsoft.ServiceModel.Samples.ICalculator" />
      </service>
    </services>

    <bindings>
      <wsHttpBinding>
        <binding name="Binding1">
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="False" />
          <!--
        The serviceCredentials behavior allows one to define a service certificate.
        A service certificate is used by a client to authenticate the service and provide message protection.
        This configuration references the "localhost" certificate installed during the setup instructions.
        -->
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

La configuración del punto de conexión de cliente consta de un nombre de configuración, una dirección absoluta para el punto de conexión de servicio, el enlace y el contrato. El enlace del cliente se configura con el adecuado Mode y clientCredentialTypedel mensaje.

<system.serviceModel>
  <client>
    <endpoint name=""
              address="http://localhost:8000/servicemodelsamples/service"
              binding="wsHttpBinding"
              bindingConfiguration="Binding1"
              contract="Microsoft.ServiceModel.Samples.ICalculator">
    </endpoint>
  </client>

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

Los pasos siguientes muestran cómo desarrollar un proveedor de tokens personalizado e integrarlo con el marco de seguridad de WCF:

  1. Escriba un proveedor de tokens personalizado.

    El ejemplo implementa un proveedor de tokens personalizado que obtiene el nombre de usuario y la contraseña. La contraseña debe coincidir con este nombre de usuario. Este proveedor de tokens personalizado es solo para fines de demostración y no se recomienda para la implementación en el mundo real.

    Para realizar esta tarea, el proveedor de tokens personalizado deriva la SecurityTokenProvider clase e invalida el GetTokenCore(TimeSpan) método . Este método crea y devuelve un nuevo UserNameSecurityToken.

    protected override SecurityToken GetTokenCore(TimeSpan timeout)
    {
        // obtain username and password from the user using console window
        string username = GetUserName();
        string password = GetPassword();
        Console.WriteLine("username: {0}", username);
    
        // return new UserNameSecurityToken containing information obtained from user
        return new UserNameSecurityToken(username, password);
    }
    
  2. Redacte un administrador de tokens de seguridad personalizado.

    SecurityTokenManager se utiliza para crear SecurityTokenProvider para el SecurityTokenRequirement concreto que se pasa en el método CreateSecurityTokenProvider. El administrador de tokens de seguridad también se usa para crear autenticadores de tokens y un serializador de tokens, pero estos no están cubiertos por este ejemplo. En este ejemplo, el administrador de token de seguridad personalizado hereda de la clase ClientCredentialsSecurityTokenManager y sobrescribe el método CreateSecurityTokenProvider para devolver un proveedor de token de nombre de usuario personalizado cuando los requisitos de token pasados indican que se solicita un proveedor de nombre de usuario.

    public class MyUserNameSecurityTokenManager : ClientCredentialsSecurityTokenManager
    {
        MyUserNameClientCredentials myUserNameClientCredentials;
    
        public MyUserNameSecurityTokenManager(MyUserNameClientCredentials myUserNameClientCredentials)
            : base(myUserNameClientCredentials)
        {
            this.myUserNameClientCredentials = myUserNameClientCredentials;
        }
    
        public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
        {
            // if token requirement matches username token return custom username token provider
            // otherwise use base implementation
            if (tokenRequirement.TokenType == SecurityTokenTypes.UserName)
            {
                return new MyUserNameTokenProvider();
            }
            else
            {
                return base.CreateSecurityTokenProvider(tokenRequirement);
            }
        }
    }
    
  3. Escriba una credencial de cliente personalizada.

    La clase de credenciales de cliente se usa para representar las credenciales configuradas para el proxy de cliente y crea el administrador de tokens de seguridad que se usa para obtener autenticadores de tokens, proveedores de tokens y un serializador de tokens.

    public class MyUserNameClientCredentials : ClientCredentials
    {
        public MyUserNameClientCredentials()
            : base()
        {
        }
    
        protected override ClientCredentials CloneCore()
        {
            return new MyUserNameClientCredentials();
        }
    
        public override SecurityTokenManager CreateSecurityTokenManager()
        {
            // return custom security token manager
            return new MyUserNameSecurityTokenManager(this);
        }
    }
    
  4. Configure el cliente para que use la credencial de cliente personalizada.

    Para que el cliente use la credencial de cliente personalizada, el ejemplo elimina la clase de credenciales de cliente predeterminada y proporciona la nueva clase de credenciales de cliente.

    static void Main()
    {
        // ...
           // Create a client with given client endpoint configuration
          CalculatorClient client = new CalculatorClient();
    
          // set new credentials
           client.ChannelFactory.Endpoint.Behaviors.Remove(typeof(ClientCredentials));
         client.ChannelFactory.Endpoint.Behaviors.Add(new MyUserNameClientCredentials());
       // ...
    }
    

En el servicio, para mostrar la información del llamante, use el PrimaryIdentity como se muestra en el ejemplo de código siguiente. Current contiene información de las notificaciones sobre el llamador actual.

static void DisplayIdentityInformation()
{
    Console.WriteLine("\t\tSecurity context identity  :  {0}",
        ServiceSecurityContext.Current.PrimaryIdentity.Name);
}

Al ejecutar el ejemplo, las solicitudes de operación y las respuestas se muestran en la ventana de la consola del cliente. Presione ENTRAR en la ventana del cliente para apagar el cliente.

Instalar el archivo por lotes

El Setup.bat archivo por lotes incluido con este ejemplo permite configurar el servidor con el certificado pertinente para ejecutar una aplicación autohospedada que requiera seguridad basada en certificados de servidor. Este archivo por lotes debe modificarse para que funcione entre equipos o para que funcione en un caso no hospedado.

A continuación se proporciona una breve introducción a las distintas secciones de los archivos por lotes para que se puedan modificar para que se ejecuten en la configuración adecuada:

  • Creación del certificado de servidor.

    Las líneas siguientes del archivo por lotes de Setup.bat crean el certificado de servidor que se va a usar. La %SERVER_NAME% variable especifica el nombre del servidor. Cambie esta variable para especificar su propio nombre de servidor. El valor predeterminado de este archivo por lotes es localhost.

    echo ************
    echo Server cert setup starting
    echo %SERVER_NAME%
    echo ************
    echo making server cert
    echo ************
    makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
    
  • Instalación del certificado de servidor en el almacén de certificados de confianza del cliente:

    Las líneas siguientes del archivo por lotes Setup.bat copian el certificado de servidor en el almacén de los usuarios de confianza del cliente. Este paso es necesario porque el sistema cliente no confía implícitamente en los certificados generados por Makecert.exe. Si ya tiene un certificado que se basa en un certificado raíz de confianza de cliente (por ejemplo, un certificado emitido por Microsoft), este paso para rellenar el almacén de certificados de cliente con el certificado de servidor no es necesario.

    certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
    

Nota:

El archivo por lotes Setup.bat está diseñado para ejecutarse desde una consola de comandos del Windows SDK. Requiere que la variable de entorno MSSDK apunte al directorio donde está instalado el SDK. Esta variable de entorno se establece automáticamente dentro de un símbolo del sistema de Windows SDK.

Para instalar y compilar el ejemplo

  1. Asegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.

  2. Para compilar la solución, siga las instrucciones de Creación de ejemplos de Windows Communication Foundation.

Para ejecutar el ejemplo en el mismo equipo

  1. Ejecute el comando Setup.bat en la carpeta de instalación de ejemplo dentro de una ventana de comandos de Visual Studio abierta con privilegios de administrador. Esto instala todos los certificados necesarios para ejecutar el ejemplo.

    Nota:

    El archivo por lotes Setup.bat está diseñado para ejecutarse desde el símbolo del sistema de Visual Studio. La variable de entorno PATH configurada en la consola de comandos de Visual Studio apunta al directorio que contiene los ejecutables necesarios para el script de Setup.bat.

  2. Inicie service.exe desde service\bin.

  3. Inicie Client.exe desde \client\bin. La actividad de cliente se muestra en la aplicación de consola cliente.

  4. En el campo del nombre de usuario, escriba un nombre de usuario.

  5. Cuando se pida la contraseña, utilice la misma cadena que escribió cuando se solicitó el nombre de usuario.

  6. Si el cliente y el servicio no pueden comunicarse, consulte Sugerencias de solución de problemas para ejemplos de WCF.

Para ejecutar el ejemplo entre equipos

  1. Cree un directorio en el equipo de servicio para los archivos binarios del servicio.

  2. Copie los archivos del programa de servicio en el directorio del servicio en el equipo destinado al servicio. Copie también los archivos Setup.bat y Cleanup.bat en el equipo de servicio.

  3. Debe tener un certificado de servidor con el nombre del sujeto que contiene el nombre de dominio completo del equipo. El archivo Service.exe.config debe actualizarse para reflejar este nuevo nombre de certificado. Puede crear un certificado de servidor modificando el archivo por lotes Setup.bat. Tenga en cuenta que el archivo setup.bat debe ejecutarse desde el Símbolo del sistema para desarrolladores de Visual Studio con privilegios de administrador. Debe establecer la variable %SERVER_NAME% en el nombre de host completo del equipo que se utiliza para hospedar el servicio.

  4. Copie el certificado de servidor en el almacén CurrentUser-TrustedPeople del cliente. No es necesario hacerlo cuando un emisor de confianza de cliente emite el certificado de servidor.

  5. En el archivo Service.exe.config del ordenador de servicio, cambie el valor de la dirección base para especificar un nombre de equipo totalmente calificado en lugar de localhost.

  6. En el equipo del servicio, ejecute service.exe desde un símbolo del sistema.

  7. Copie los archivos de programa cliente de la carpeta \client\bin\, en la carpeta específica del idioma, en el equipo cliente.

  8. En el archivo Client.exe.config del equipo cliente, cambie el valor de dirección del punto de conexión para que coincida con la nueva dirección del servicio.

  9. En el equipo cliente, inicie Client.exe desde una ventana de línea de comandos.

  10. Si el cliente y el servicio no pueden comunicarse, consulte Sugerencias de solución de problemas para ejemplos de WCF.

Para limpiar después de la muestra.

  1. Ejecute Cleanup.bat en la carpeta samples una vez que haya terminado de ejecutar el ejemplo.