Consumir Web Service com Certificado Digital

Cada vez mais, a utilização do Certificado Digital como forma de autenticação e autorização é utilizada pelo mercado. Grosso modo: quando você extrai um certificado digital, você extrai as raízes intermediárias e a chave pública. Assim isto é “instalado” nos servidores a qual você precisará se autenticar.

Quando você tenta se autenticar com este servidor, ele verifica suas credenciais e faz um match com as que ele possui em seu servidor. Caso o servidor encontre suas credenciais, ele extrai alguns dados e verifica se você tem acesso à aplicação ou um módulo específico. Se você tiver autorização, ótimo, caso contrário terá o seu acesso negado.

Recentemente precisei desenvolver um cliente que consultava um web service (asmx) que exigia a autenticação por certificado digital.

Para facilitar a vida, eu criei uma classe-helper que herda o web references adicionado anteriormente. Então escrevi algumas linhas de código no construtor para fazer a autenticação.

Vamos supor que o serviço que você precisa consumir chama-se NorthwindWS. Você irá precisar adicionar uma referência. Obviamente você também precisará de um certificado digital válido e que tenha autorização no servidor do web service que você deseja se autenticar.

1) Clique com o botão direito em Service References > Add Service Reference. Quando abrir a janela Add Service Reference, clique no botão Advanced. Depois é só clicar em Add Web Reference.

2) Em Url, digite a Url onde se encontra o serviço, clique no botão para encontrar os métodos disponíveis e clique em Add Reference. Neste momento você verá o serviço adicionado na pasta Web References.

3) Crie uma classe chamada WebServiceHelper e digite o seguinte conteúdo:

using System;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates; 
// Glossário:
// --------------
// + Thumbprint: impressão digital de um certificado digital. Para consultar um thumbprint,
// abra o internet explorer, clique em Ferramentas > Opções da Internet >
// Aba "Conteúdo" > Botão "Certificados" >
// Dê dois cliques no certificado que deseja consultar > Aba "Detalhes" >
// Procure o ultimo item "Impressão Digital" 

namespace MeuProjeto
{
    public class WebServiceHelper : NorthwindWS
    {
        /// <summary>
        /// No construtor da classe obtemos as credenciais do certificado digital
        /// instalado nas máquinas que irão consumir o web service.
        /// Posteriormente são estas crendenciais que serão passadas para 
        /// o web service NorthwindWS.
        /// </summary>
        public WebServiceHelper()
        {
            // Armazenamos o local físico onde o certificado é armazenado e gerenciado.            
            X509Store store = new X509Store(
                StoreName.My,              // Queremos abrir somente os certificados pessoais.
                StoreLocation.LocalMachine // Queremos somente os certificados locais
            );

            // Se precisar configurar um proxy de saída, utilize as duas linhas.
            // Caso contrário, pode ignorar
            this.Proxy = new WebProxy(
                String.Format("{0}:{1}", "endereco_proxy", "porta"));
            this.Proxy.Credentials = new NetworkCredential("usuario", "senha");

            // Também iremos precisar reconfigurar a store para, ao invés de
            // obter os certificados assinados para a máquina local, obter os
            // certificados assinados para o usuário corrente.
            store = new X509Store(StoreName.My, StoreLocation.CurrentUser);

            // Abrimos o local físico configurado previamente no modo "somente para leitura".
            store.Open(OpenFlags.ReadOnly);

            // Iremos varrer os certificados encontrados e buscar aquele que nos interessa.
                     X509Certificate cert = (
                // Chama a função para pesquisar o certificado que queremos encontrar.
                store.Certificates.Find(
                    X509FindType.FindByThumbprint, // Iremos pesquisar por Thumbprint *
                                  "xxxxxxxxxxxxxxx".ToUpper(), // Número do Thumprint (Remova os espaços) *
                    false // Vamos pesquisar certificados válidos e não
                                             // validos que atendam os demais critérios da função.
            ))[0]; // Como a função retorna uma coleção, iremos pegar o
                                 // primeiro item, que é o certificado que desejamos.			                  

                     // Adicionamos o certificado no web service da Junta Comercial.
            this.ClientCertificates.Add(cert);
        }
    }
}

Agora é só fazer a chamada ao método desejado através da classe WebServiceHelper. Exemplo:

WebServiceHelper ws = new WebServiceHelper();

ws.Consultar();

Espero que tenha ajudado. Qualquer dúvida não hesite em entrar em contato!

Até a próxima!

Etiquetado ,

6 pensamentos sobre “Consumir Web Service com Certificado Digital

  1. Fábio Freitas disse:

    Parabéns pelo artigo,

    Este exemplo funciona para aplicações WebForm?

    Desde já agradeço,

    Fábio Freitas

  2. Maicon disse:

    Muito bom artigo… parabens!

  3. Hudson Alves disse:

    Muito bom o artigo… direto ao ponto.

  4. Dos exemplos que pesquisei na Internet o seu foi o melhor explicado e desenvolvido. Parabéns, ajudou bastante

  5. Evando, excelente dica! Muito obrigado. Tem como você fazer um exemplo de como fazer a assinatura digital de um documento xml?

  6. Reinaldo Guilherme disse:

    Seu artigo está excelente. Utilizei essa implementação e funcionou perfeitamente, porém, no ambiente de desenvolvimento. Quando publico a aplicação, ao tentar realizar uma consulta ocorre o erro:
    Server Error in ‘/Sistema’ Application.
    Object reference not set to an instance of an object.
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.NullReferenceException: Object reference not set to an instance of an object. etc…
    Tem alguma ideia do que possa ser? Na depuração não ocorre erro algum.

Deixar mensagem para Fábio Freitas Cancelar resposta