Compartilhar via


Fornecedor de token

Este exemplo demonstra como implementar um provedor de token personalizado. Um provedor de token no WCF (Windows Communication Foundation) é usado para fornecer credenciais à infraestrutura de segurança. O provedor de token em geral examina o destino e emite as credenciais apropriadas para que a infraestrutura de segurança possa proteger a mensagem. O WCF é fornecido com o provedor de token padrão do Gerenciador de Credenciais. O WCF também é fornecido com um provedor de token CardSpace. Os provedores de token personalizados são úteis nos seguintes casos:

  • Se você tiver um repositório de credenciais com o qual esses provedores de token não podem operar.

  • Se você quiser fornecer o próprio mecanismo personalizado para transformar as credenciais a partir do ponto em que o usuário fornece os detalhes para quando a estrutura de cliente do WCF usa as credenciais.

  • Se você estiver criando um token personalizado.

Este exemplo mostra como criar um provedor de token personalizado que transforma a entrada do usuário em um formato diferente.

Este exemplo demonstra o seguinte:

  • Como um cliente pode autenticar usando um par de nome de usuário/senha.

  • Como um cliente pode ser configurado com um provedor de token personalizado.

  • Como o servidor pode validar as credenciais do cliente usando uma senha com um UserNamePasswordValidator personalizado que valida se o nome de usuário e a senha correspondem.

  • Como o servidor é autenticado pelo cliente usando o certificado X.509 do servidor.

Este exemplo também mostra como a identidade do chamador é acessível após o processo de autenticação de token personalizado.

O serviço expõe um único ponto de extremidade para se comunicar com o serviço, definido usando o arquivo de configuração App.config. O ponto de extremidade é composto por um endereço, uma associação e um contrato. A associação é configurada com um wsHttpBinding padrão, que usa a segurança da mensagem por padrão. Este exemplo define o wsHttpBinding padrão para usar a autenticação do nome de usuário. O serviço também configura o certificado de serviço usando o comportamento serviceCredentials. O comportamento serviceCredentials permite configurar um certificado de serviço. Um certificado de serviço é usado por um cliente para autenticar o serviço e fornecer proteção de mensagem. A configuração a seguir faz referência ao certificado localhost instalado durante a configuração de exemplo, conforme descrito nas instruções de instalação a seguir.

<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>

A configuração do ponto de extremidade do cliente consiste em um nome de configuração, um endereço absoluto para o ponto de extremidade de serviço, a associação e o contrato. A associação do cliente é configurada com o modo Mode e a mensagem clientCredentialType apropriados.

<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>

As etapas a seguir mostram como desenvolver um provedor de token personalizado e integrá-lo à estrutura de segurança do WCF:

  1. Grave um provedor de token personalizado.

    O exemplo implementa um provedor de token personalizado que obtém o nome de usuário e a senha. A senha deve corresponder a esse nome de usuário. Esse provedor de token personalizado é somente para fins de demonstração e não é recomendada sua implantação do mundo real.

    Para executar essa tarefa, o provedor de token personalizado deriva a classe SecurityTokenProvider e substitui o método GetTokenCore(TimeSpan). Esse método cria e retorna um novo 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. Grave o gerenciador de tokens de segurança personalizado.

    A classe SecurityTokenManager é usada para criar SecurityTokenProvider para o SecurityTokenRequirement específico que é passado para ela no método CreateSecurityTokenProvider. O gerenciador de tokens de segurança também é usado para criar autenticadores de token e um serializador de token, mas não são tratados neste exemplo. Neste exemplo, o gerenciador de tokens de segurança personalizado herda da classe ClientCredentialsSecurityTokenManager e substitui o método CreateSecurityTokenProvider para retornar o provedor de token de nome de usuário personalizado quando os requisitos de token passados indicam que o provedor de nome de usuário é solicitado.

    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. Grave uma credencial de cliente personalizada.

    A classe de credenciais do cliente é usada para representar as credenciais configuradas para o proxy do cliente e cria o gerenciador de tokens de segurança que será usado para obter autenticadores, provedores e serializadores de token.

    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 o cliente para usar a credencial de cliente personalizada.

    Para que o cliente possa usar a credencial personalizada, o exemplo exclui a classe de credencial de cliente padrão e fornece a nova classe de credencial 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());
       // ...
    }
    

No serviço, para exibir as informações do chamador, use as PrimaryIdentity mostradas no exemplo de código a seguir. O Current contém informações de declarações sobre o chamador atual.

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

Quando você executa a amostra, as solicitações de operação e as respostas são exibidas na janela do console do cliente. Pressione ENTER na janela do cliente para desligar o cliente.

Arquivo de configuração em lote

O arquivo Setup.bat em lote, incluído com este exemplo, permite que você configure o servidor com o certificado pertinente para executar um aplicativo auto-hospedado que exige segurança baseada em certificado do servidor. Esse arquivo em lote precisa ser modificado para funcionar em computadores ou em um caso não hospedado.

A seguir está breve visão geral das diferentes seções dos arquivos em lote que podem ser modificados para executar a configuração apropriada:

  • Criação do certificado do servidor.

    As linhas a seguir do arquivo em lote Setup.bat criam o certificado do servidor a ser usado. A variável %SERVER_NAME% especifica o nome do servidor. Altere essa variável para especificar o nome do seu próprio servidor. O valor padrão neste arquivo de lote é 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
    
  • Instalação do certificado do servidor no repositório de certificados confiáveis do cliente:

    As linhas a seguir no arquivo em lote Setup.bat copiam o certificado do servidor no repositório de pessoas confiáveis do cliente. Essa etapa é necessária porque os certificados gerados por Makecert.exe não são implicitamente confiáveis pelo sistema do cliente. Se você já tiver um certificado com raiz em um certificado raiz confiável do cliente, por exemplo, um certificado emitido pela Microsoft, essa etapa de preenchimento do repositório de certificados do cliente com o certificado do servidor não será necessária.

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

Observação

O arquivo de lote Setup.bat foi projetado para ser executado a partir de um prompt de comando do SDK do Windows. Ele requer que a variável de ambiente MSSDK aponte para o diretório onde o SDK está instalado. Essa variável de ambiente é definida automaticamente em um Prompt de Comando do SDK do Windows.

Para configurar e compilar a amostra

  1. Verifique se você executou o Procedimento de instalação única para os exemplos do Windows Communication Foundation.

  2. Para compilar a solução, siga as instruções contidas em Como compilar as amostras do Windows Communication Foundation.

Para executar a amostra no mesmo computador

  1. Execute Setup.bat na pasta de instalação de exemplo dentro de um prompt de comando do Visual Studio aberto com privilégios de administrador. Isso instalará todos os certificados necessários para executar o exemplo.

    Observação

    O arquivo de lote Setup.bat foi projetado para ser executado a partir de um prompt de comando do Visual Studio. A variável de ambiente PATH definida no prompt de comando do Visual Studio aponta para o diretório que contém executáveis exigidos pelo script Setup.bat.

  2. Inicialize o service.exe a partir do service\bin.

  3. Inicialize o Client.exe a partir do \client\bin. A atividade do cliente é exibida no aplicativo do console do cliente.

  4. No prompt de nome de usuário, digite um nome de usuário.

  5. No prompt de senha, use a mesma cadeia de caracteres que foi digitada para o prompt de nome de usuário.

  6. Se o cliente e o serviço não puderem se comunicar, confira Dicas de solução de problemas para exemplos de WCF.

Para executar a amostra em vários computadores

  1. Crie um diretório no computador de serviço para os binários de serviço.

  2. Copie os arquivos do programa de serviço para o diretório de serviço no computador de serviço. Copie também os arquivos Setup.bat e Cleanup.bat para o computador de serviço.

  3. Você precisa ter um certificado de servidor com o nome da entidade que contém o nome de domínio totalmente qualificado do computador. O arquivo Service.exe.config precisa ser atualizado para refletir esse novo nome de certificado. Você pode criar um certificado de servidor modificando o arquivo em lote Setup.bat. Observe que o arquivo setup.bat deve ser executado em um Prompt de Comando do Desenvolvedor para Visual Studio aberto com privilégios de administrador. Você precisa definir a variável %SERVER_NAME% como o nome de host totalmente qualificado do computador usado para hospedar o serviço.

  4. Copie o certificado do servidor no repositório CurrentUser-TrustedPeople do cliente. Você não precisa fazer isso quando o certificado do servidor é emitido por um emissor confiável do cliente.

  5. No arquivo Service.exe.config no computador de serviço, altere o valor do endereço base para especificar um nome de computador totalmente qualificado em vez de localhost.

  6. No computador de serviço, inicie o service.exe a partir de um prompt de comando.

  7. Copie os arquivos do programa cliente da pasta \client\bin\ na pasta específica do idioma, para o computador cliente.

  8. No arquivo Client.exe.config do computador cliente, altere o valor do endereço do ponto de extremidade para que ele corresponda ao novo endereço do serviço.

  9. No computador cliente, inicie Client.exe a partir de uma janela do prompt de comando.

  10. Se o cliente e o serviço não puderem se comunicar, confira Dicas de solução de problemas para exemplos de WCF.

Para fazer uma limpeza após o exemplo

  1. Execute Cleanup.bat na pasta de amostras depois de concluir a execução da amostra.