Protegendo clientes

No WCF (Windows Communication Foundation), o serviço determina os requisitos de segurança para os clientes. Ou seja, o serviço especifica qual modo de segurança usar e se o cliente deve ou não fornecer uma credencial. O processo de proteção de um cliente, portanto, é simples: use os metadados obtidos do serviço (se tiverem sido publicados) e compile um cliente. Os metadados especificam como configurar o cliente. Se o serviço exigir que o cliente forneça uma credencial, você deverá obter uma credencial que atenda ao requisito. Este tópico discute o processo mais detalhadamente. Para saber mais sobre como criar um serviço seguro, confira Proteção de serviços.

O serviço especifica a segurança

Por padrão, as associações WCF têm recursos de segurança habilitados. (A exceção é BasicHttpBinding.) Portanto, se o serviço foi criado usando o WCF, há uma maior chance de que ele implemente a segurança para garantir a autenticação, a confidencialidade e a integridade. Nesse caso, os metadados que o serviço fornece indicarão o que é necessário para estabelecer um canal de comunicação seguro. Se os metadados de serviço não incluírem nenhum requisito de segurança, não haverá como impor um esquema de segurança, como o protocolo SSL (Secure Sockets Layer) via HTTP, em um serviço. No entanto, se o serviço exigir que o cliente forneça uma credencial, o desenvolvedor, o implantador ou o administrador cliente deverá fornecer a credencial real que o cliente usará para se autenticar no serviço.

Obtenção dos metadados

Ao criar um cliente, a primeira etapa é obter os metadados para o serviço com o qual o cliente se comunicará. Isso pode ser feito de duas maneiras. Primeiro, se o serviço publicar um ponto de extremidade MEX (troca de metadados) ou disponibilizar seus metadados por HTTP ou HTTPS, você poderá baixar os metadados usando a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe), que gera arquivos de código para um cliente, bem como um arquivo de configuração. (Para saber mais sobre como usar a ferramenta, confira Acessar serviços usando um cliente WCF.) Se o serviço não publicar um ponto de extremidade MEX e também não disponibilizar seus metadados por HTTP ou HTTPS, entre em contato com o criador do serviço para obter a documentação que descreve os requisitos de segurança e os metadados.

Importante

Recomendamos que os metadados sejam provenientes de uma fonte confiável e que não sejam adulterados. Os metadados recuperados usando o protocolo HTTP são enviados em texto não criptografado e podem ser adulterados. Se o serviço usar as propriedades HttpsGetEnabled e HttpsGetUrl, use a URL fornecida pelo criador do serviço para baixar os dados usando o protocolo HTTPS.

Validação da segurança

As fontes de metadados podem ser divididas em duas categorias amplas: fontes confiáveis e fontes não confiáveis. Se você confiar em uma origem e tiver baixado o código do cliente e outros metadados do ponto de extremidade MEX seguro dessa fonte, poderá compilar o cliente, fornecer as credenciais certas e executá-lo sem outras preocupações.

No entanto, se você optar por baixar um cliente e metadados de uma fonte que você conhece pouco, valide as medidas de segurança usadas pelo código. Por exemplo, você não deve simplesmente criar um cliente que envia suas informações pessoais ou financeiras para um serviço, a menos que o serviço exija confidencialidade e integridade (no mínimo). Você deve confiar no proprietário do serviço na medida em que estiver disposto a divulgar essas informações, pois elas estarão visíveis para elas.

Portanto, como regra, ao usar código e metadados de uma origem não confiável, verifique o código e os metadados para garantir que atendam ao nível de segurança necessário.

Configuração de uma credencial de cliente

A configuração de uma credencial de cliente em um cliente consiste em duas etapas:

  1. Determinar o tipo de credencial do cliente que o serviço exige. Isso é feito por um de dois métodos. Primeiro, se você tiver a documentação do criador do serviço, ele deverá especificar o tipo de credencial do cliente (se houver) que o serviço requer. Em segundo lugar, se você tiver apenas um arquivo de configuração gerado pela ferramenta Svcutil.exe, poderá examinar as associações individuais para determinar qual tipo de credencial é necessário.

  2. Especificar uma credencial de cliente real. A credencial do cliente real é chamada de valor de credencial do cliente para distingui-la do tipo. Por exemplo, se o tipo de credencial do cliente especificar um certificado, você deverá fornecer um certificado X.509 emitido por uma autoridade de certificação em que o serviço confia.

Determinar o tipo de credencial de cliente

Se você tiver o arquivo de configuração gerado pela ferramenta Svcutil.exe, examine a seção <associações> para determinar qual tipo de credencial do cliente é necessário. Dentro da seção há elementos de associação que especificam os requisitos de segurança. Especificamente, examine o elemento <segurança> de cada associação. Esse elemento inclui o atributo mode, que você pode definir como um dos três valores possíveis (Message, Transport ou TransportWithMessageCredential). O valor do atributo determina o modo, e o modo determina qual dos elementos filho é significativo.

O elemento <security> pode conter um elemento <transport> ou <message>, ou ambos. O elemento significativo é aquele que corresponde ao modo de segurança. Por exemplo, o código a seguir especifica que o modo de segurança é "Message", e o tipo de credencial do cliente para o elemento <message> é "Certificate". Nesse caso, o elemento <transport> pode ser ignorado. No entanto, o elemento <message> especifica que um certificado X.509 deve ser fornecido.

<wsHttpBinding>  
    <binding name="WSHttpBinding_ICalculator">  
       <security mode="Message">  
           <transport clientCredentialType="Windows"
                      realm="" />  
           <message clientCredentialType="Certificate"
                    negotiateServiceCredential="true"  
                    algorithmSuite="Default"
                    establishSecurityContext="true" />  
       </security>  
    </binding>  
</wsHttpBinding>  

Observe que, se o atributo clientCredentialType estiver definido como "Windows", conforme mostrado no exemplo a seguir, você não precisará fornecer um valor de credencial real. Isso ocorre porque a segurança integrada do Windows fornece a credencial real (um token Kerberos) da pessoa que está executando o cliente.

<security mode="Message">  
    <transport clientCredentialType="Windows "
        realm="" />  
</security>  

Configuração do valor de credencial de cliente

Se for determinado que o cliente deve fornecer uma credencial, use o método apropriado para configurar o cliente. Por exemplo, para definir um certificado do cliente, use o método SetCertificate.

Uma forma comum de credenciais é o certificado X.509. Você pode fornecer a credencial de duas maneiras:

  • Programando-a no código do cliente (usando o método SetCertificate).

Adicionando uma seção <comportamentos> do arquivo de configuração para o cliente e usando o elemento clientCredentials (mostrado abaixo).

Definindo um valor <clientCredentials> no código

Para definir um valor <clientCredentials> no código, você deve acessar a propriedade ClientCredentials da classe ClientBase<TChannel>. A propriedade retorna um objeto ClientCredentials que permite o acesso a vários tipos de credencial, conforme mostrado na tabela a seguir.

Propriedade ClientCredential Descrição Observações
ClientCertificate Retorna um X509CertificateInitiatorClientCredential Representa um certificado X.509 fornecido pelo cliente para se autenticar no serviço.
HttpDigest Retorna um HttpDigestClientCredential Representa uma credencial de HTTP digest. A credencial é um hash do nome de usuário e senha.
IssuedToken Retorna um IssuedTokenClientCredential Representa um token de segurança personalizado emitido por um Serviço de Token de Segurança, normalmente usado em cenários de federação.
Peer Retorna um PeerCredential Representa uma credencial de par para participação em uma malha ponto a ponto em um domínio do Windows.
ServiceCertificate Retorna um X509CertificateRecipientClientCredential Representa um certificado X.509 fornecido pelo serviço em uma negociação fora de banda.
UserName Retorna um UserNamePasswordClientCredential Representa um par de nome de usuário e senha.
Windows Retorna um WindowsClientCredential Representa uma credencial de cliente do Windows (uma credencial Kerberos). As propriedades da classe são somente leitura.

Configuração de um valor <clientCredentials> em Configuração

Os valores de credencial são especificados usando um comportamento de ponto de extremidade como elementos filho do elemento <clientCredentials>. O elemento usado depende do tipo de credencial do cliente. Por exemplo, o exemplo a seguir mostra a configuração para definir um certificado X.509 usando <<clientCertificate>.

<configuration>  
  <system.serviceModel>  
    <behaviors>  
      <endpointBehaviors>
        <behavior name="myEndpointBehavior">  
          <clientCredentials>  
            <clientCertificate findvalue="myMachineName"
            storeLocation="Current" X509FindType="FindBySubjectName" />  
          </clientCredentials>  
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>  
</configuration>  

Para definir a credencial do cliente na configuração, adicione um elemento <endpointBehaviors> ao arquivo de configuração. Além disso, o elemento de comportamento adicionado deve estar vinculado ao ponto de extremidade do serviço usando o atributo behaviorConfiguration do <ponto extremidade> do elemento <cliente >, conforme mostrado no exemplo a seguir. O valor do atributo behaviorConfiguration deve corresponder ao valor do atributo name de comportamento.

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

Observação

Alguns dos valores de credencial do cliente não podem ser definidos usando arquivos de configuração de aplicativo, por exemplo, nome de usuário e senha, ou valores de usuário e senha do Windows. Esses valores de credencial só podem ser especificados no código.

Para saber mais sobre como configurar a credencial do cliente, confira Como: especificar valores de credencial de cliente.

Observação

ClientCredentialType é ignorado quando SecurityMode é definido como "TransportWithMessageCredential", conforme mostrado na configuração de exemplo a seguir.

<wsHttpBinding>  
    <binding name="PingBinding">  
        <security mode="TransportWithMessageCredential"  >  
           <message  clientCredentialType="UserName"
               establishSecurityContext="false"
               negotiateServiceCredential="false" />  
           <transport clientCredentialType="Certificate"  />  
         </security>  
    </binding>  
</wsHttpBinding>  

Confira também