Como: proteger um serviço com um certificado X.509

Proteger um serviço com um certificado X.509 é uma técnica básica que a maioria das associações no WCF (Windows Communication Foundation) usa. Este tópico explica as etapas de configuração de um serviço auto-hospedado com um certificado X.509.

Um pré-requisito é um certificado válido que pode ser usado para autenticar o servidor. O certificado deve ser emitido para o servidor por uma autoridade de certificação confiável. Se o certificado não for válido, qualquer cliente que tentar usar o serviço não confiará no serviço e, consequentemente, nenhuma conexão será feita. Para obter mais informações sobre o uso de certificados, consulte Trabalhar com certificados.

Para configurar um serviço com um certificado usando código

  1. Crie o contrato de serviço e o serviço implementado. Para obter mais informações, consulte Projetando e implementando serviços.

  2. Crie uma instância da classe WSHttpBinding e defina seu modo de segurança como Message, conforme mostrado no código a seguir.

    // Create a binding and set the security mode to Message.
    WSHttpBinding b = new WSHttpBinding(SecurityMode.Message);
    
    ' Create a binding and set the security mode to Message.
    Dim b As New WSHttpBinding(SecurityMode.Message)
    
  3. Crie duas variáveis Type, uma para o tipo de contrato e outra para o contrato implementado, conforme mostrado no código a seguir.

    Type contractType = typeof(ICalculator);
    Type implementedContract = typeof(Calculator);
    
    Dim contractType = GetType(ICalculator)
    Dim implementedContract = GetType(Calculator)
    
  4. Crie uma instância da classe Uri para o endereço básico do serviço. Como o WSHttpBinding usa transporte HTTP, o URI (Uniform Resource Identifier) deve começar com esse esquema ou o WCF (Windows Communication Foundation) lançará uma exceção quando o serviço for aberto.

    Uri baseAddress = new Uri("http://localhost:8044/base");
    
    Dim baseAddress As New Uri("http://localhost:8044/base")
    
  5. Crie uma nova instância da classe ServiceHost com a variável de tipo de contrato implementada e o URI.

    ServiceHost sh = new ServiceHost(implementedContract, baseAddress);
    
    Dim sh As New ServiceHost(implementedContract, baseAddress)
    
  6. Adicione um ServiceEndpoint ao serviço usando o método AddServiceEndpoint. Passe o contrato, a associação e um endereço de ponto de extremidade para o construtor, conforme mostrado no código a seguir.

    sh.AddServiceEndpoint(contractType, b, "Calculator");
    
    sh.AddServiceEndpoint(contractType, b, "Calculator")
    
  7. Opcional. Para recuperar metadados do serviço, crie um novo objeto ServiceMetadataBehavior e defina a propriedade HttpGetEnabled como true.

    ServiceMetadataBehavior sm = new ServiceMetadataBehavior();
    sm.HttpGetEnabled = true;
    sh.Description.Behaviors.Add(sm);
    
    Dim sm As New ServiceMetadataBehavior()
    sm.HttpGetEnabled = True
    
    With sh
        .Description.Behaviors.Add(sm)
    
  8. Use o método SetCertificate da classe X509CertificateRecipientServiceCredential para adicionar o certificado válido ao serviço. O método pode usar um dos vários métodos para encontrar um certificado. Este exemplo usa a enumeração FindBySubjectName. A enumeração especifica que o valor fornecido é o nome da entidade para a qual o certificado foi emitido.

    sh.Credentials.ServiceCertificate.SetCertificate(
        StoreLocation.LocalMachine ,StoreName.My,
        X509FindType.FindBySubjectName ,"localhost");
    
    .Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, _
                                                   StoreName.My, _
                                                   X509FindType.FindBySubjectName, _
                                                   "localhost")
    
  9. Chame o método Open para iniciar o serviço de escuta. Se você estiver criando um aplicativo de console, chame o método ReadLine para manter o serviço no estado de escuta.

    sh.Open();
    Console.WriteLine("Listening");
    Console.ReadLine();
    
    .Open()
    Console.WriteLine("Listening")
    Console.ReadLine()
    

Exemplo

O exemplo a seguir usa o método SetCertificate para configurar um serviço com um certificado X.509.

// Create a binding and set the security mode to Message.
WSHttpBinding b = new WSHttpBinding(SecurityMode.Message);

Type contractType = typeof(ICalculator);
Type implementedContract = typeof(Calculator);

Uri baseAddress = new Uri("http://localhost:8044/base");

ServiceHost sh = new ServiceHost(implementedContract, baseAddress);

sh.AddServiceEndpoint(contractType, b, "Calculator");

ServiceMetadataBehavior sm = new ServiceMetadataBehavior();
sm.HttpGetEnabled = true;
sh.Description.Behaviors.Add(sm);

sh.Credentials.ServiceCertificate.SetCertificate(
    StoreLocation.LocalMachine ,StoreName.My,
    X509FindType.FindBySubjectName ,"localhost");

sh.Open();
Console.WriteLine("Listening");
Console.ReadLine();
sh.Close();
' Create a binding and set the security mode to Message.
Dim b As New WSHttpBinding(SecurityMode.Message)

Dim contractType = GetType(ICalculator)
Dim implementedContract = GetType(Calculator)

Dim baseAddress As New Uri("http://localhost:8044/base")

Dim sh As New ServiceHost(implementedContract, baseAddress)

sh.AddServiceEndpoint(contractType, b, "Calculator")

Dim sm As New ServiceMetadataBehavior()
sm.HttpGetEnabled = True

With sh
    .Description.Behaviors.Add(sm)

    .Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, _
                                                   StoreName.My, _
                                                   X509FindType.FindBySubjectName, _
                                                   "localhost")

    .Open()
    Console.WriteLine("Listening")
    Console.ReadLine()
    .Close()
End With

Compilando o código

Os namespaces a seguir são necessários para compilar o código:

Confira também