Compartilhar via


Ponto de extremidade de metadados seguros personalizados

A amostra de CustomMexEndpoint demonstra como implementar um serviço com um ponto de extremidade de metadados seguro que usa uma das associações de troca de não metadados e como configurar a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe) ou clientes para buscar os metadados desse ponto de extremidade de metadados. Há duas associações fornecidas pelo sistema disponíveis para expor pontos de extremidade de metadados: mexHttpBinding e mexHttpsBinding. mexHttpBinding é usado para expor um ponto de extremidade de metadados por HTTP de maneira não segura. mexHttpsBinding é usado para expor um ponto de extremidade de metadados por HTTP de maneira segura. Esta amostra ilustra como expor um ponto de extremidade de metadados seguro usando o WSHttpBinding. Você gostaria de fazer isso quando quiser alterar as configurações de segurança na associação, mas não deseja usar HTTPS. Se você usar o mexHttpsBinding, seu ponto de extremidade de metadados será seguro, mas não há como modificar as configurações de associação.

Observação

O procedimento de instalação e as instruções de compilação dessa amostra estão no final deste tópico.

Serviço

O serviço nesta amostra tem dois pontos de extremidade. O ponto de extremidade do aplicativo atende ao contrato ICalculator em um WSHttpBinding com ReliableSession habilitado e segurança Message usando certificados. O ponto de extremidade de metadados também usa WSHttpBinding, com as mesmas configurações de segurança, mas sem ReliableSession. Aqui temos a configuração relevante:

<services>
    <service name="Microsoft.ServiceModel.Samples.CalculatorService"
             behaviorConfiguration="CalculatorServiceBehavior">
     <!-- use base address provided by host -->
     <endpoint address=""
       binding="wsHttpBinding"
       bindingConfiguration="Binding2"
       contract="Microsoft.ServiceModel.Samples.ICalculator" />
     <endpoint address="mex"
       binding="wsHttpBinding"
       bindingConfiguration="Binding1"
       contract="IMetadataExchange" />
     </service>
 </services>
 <bindings>
   <wsHttpBinding>
     <binding name="Binding1">
       <security mode="Message">
         <message clientCredentialType="Certificate" />
       </security>
     </binding>
     <binding name="Binding2">
       <reliableSession inactivityTimeout="00:01:00" enabled="true" />
       <security mode="Message">
         <message clientCredentialType="Certificate" />
       </security>
     </binding>
   </wsHttpBinding>
 </bindings>

Em muitas das outras amostras, o ponto de extremidade de metadados usa o padrão mexHttpBinding, que não é seguro. Aqui, os metadados são protegidos usando WSHttpBinding com segurança Message. Para que os clientes de metadados recuperem esses metadados, eles devem ser configurados com uma associação correspondente. Esta amostra demonstra dois desses clientes.

O primeiro cliente usa Svcutil.exe para buscar os metadados e gerar o código e a configuração do cliente no tempo do design. Como o serviço usa uma associação não padrão para os metadados, a ferramenta Svcutil.exe deve ser configurada especificamente para que possa obter os metadados do serviço usando essa associação.

O segundo cliente usa o MetadataResolver para buscar dinamicamente os metadados de um contrato conhecido e, em seguida, invocar operações no cliente gerado dinamicamente.

Cliente Svcutil

Ao usar a associação padrão para hospedar seu ponto de extremidade IMetadataExchange, você pode executar Svcutil.exe com o endereço desse ponto de extremidade:

svcutil http://localhost/servicemodelsamples/service.svc/mex

e isso funciona. Mas nesta amostra, o servidor usa um ponto de extremidade não padrão para hospedar os metadados. Portanto, Svcutil.exe deve ser instruído a usar a associação correta. Isso pode ser feito usando um arquivo Svcutil.exe.config.

O arquivo Svcutil.exe.config parece um arquivo de configuração de cliente normal. Os únicos aspectos incomuns são o nome e o contrato do ponto de extremidade do cliente:

<endpoint name="http"
          binding="wsHttpBinding"
          bindingConfiguration="Binding1"
          behaviorConfiguration="ClientCertificateBehavior"
          contract="IMetadataExchange" />

O nome do ponto de extremidade deve ser o nome do esquema do endereço onde os metadados estão hospedados e o contrato de ponto de extremidade deve ser IMetadataExchange. Assim, quando Svcutil.exe é executado com uma linha de comando, como a seguinte:

svcutil http://localhost/servicemodelsamples/service.svc/mex

ele procura o ponto de extremidade chamado "http" e o contrato IMetadataExchange para configurar a associação e o comportamento da troca de comunicação com o ponto de extremidade de metadados. O resto do arquivo de Svcutil.exe.config na amostra especifica as credenciais de configuração e comportamento de associação para corresponder à configuração do servidor do ponto de extremidade de metadados.

Para que Svcutil.exe escolha a configuração no Svcutil.exe.config, Svcutil.exe deve estar no mesmo diretório que o arquivo de configuração. Como resultado, você deve copiar Svcutil.exe do seu local de instalação para o diretório que contém o arquivo Svcutil.exe.config. Em seguida, a partir deste diretório, execute o seguinte comando:

.\svcutil.exe http://localhost/servicemodelsamples/service.svc/mex

O ".\" à esquerda garante que a cópia de Svcutil.exe neste diretório (aquele que tem um Svcutil.exe.config correspondente) seja executada.

Cliente MetadataResolver

Se o cliente souber o contrato e como falar com os metadados no tempo de design, o cliente pode descobrir dinamicamente a associação e o endereço dos pontos de extremidade do aplicativo usando o MetadataResolver. Este cliente da amostra demonstra isso, mostrando como configurar a associação e as credenciais usadas por MetadataResolver criando e configurando um MetadataExchangeClient.

As mesmas informações de associação e certificado exibidas no Svcutil.exe.config podem ser especificadas de forma imperativa no MetadataExchangeClient:

// Specify the Metadata Exchange binding and its security mode
WSHttpBinding mexBinding = new WSHttpBinding(SecurityMode.Message);
mexBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;

// Create a MetadataExchangeClient for retrieving metadata, and set the // certificate details
MetadataExchangeClient mexClient = new MetadataExchangeClient(mexBinding);
mexClient.SoapCredentials.ClientCertificate.SetCertificate(    StoreLocation.CurrentUser, StoreName.My,
    X509FindType.FindBySubjectName, "client.com");
mexClient.SoapCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust;
mexClient.SoapCredentials.ServiceCertificate.SetDefaultCertificate(    StoreLocation.CurrentUser, StoreName.TrustedPeople,
    X509FindType.FindBySubjectName, "localhost");

Com o mexClient configurado, podemos enumerar os contratos nos quais estamos interessados e usar MetadataResolver para buscar uma lista de pontos de extremidade com esses contratos:

// The contract we want to fetch metadata for
Collection<ContractDescription> contracts = new Collection<ContractDescription>();
ContractDescription contract = ContractDescription.GetContract(typeof(ICalculator));
contracts.Add(contract);
// Find endpoints for that contract
EndpointAddress mexAddress = new EndpointAddress(ConfigurationManager.AppSettings["mexAddress"]);
ServiceEndpointCollection endpoints = MetadataResolver.Resolve(contracts, mexAddress, mexClient);

Por fim, podemos usar as informações desses pontos de extremidade para inicializar a associação e o endereço de um ChannelFactory usado para criar canais para se comunicar com os pontos de extremidade do aplicativo.

ChannelFactory<ICalculator> cf = new ChannelFactory<ICalculator>(endpoint.Binding, endpoint.Address);

O ponto chave deste cliente de amostra é demonstrar que, se você estiver usando MetadataResolver e precisar especificar associações ou comportamentos personalizados para a comunicação de troca de metadados, você pode usar um MetadataExchangeClient para especificar essas configurações personalizadas.

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 do exemplo. Isso instalará todos os certificados necessários para executar a amostra. Observe que Setup.bat usa a ferramenta FindPrivateKey.exe, que é instalada executando setupCertTool.bat das Amostras de Procedimento de Instalação Única para o Windows Communication Foundation.

  2. Execute o aplicativo cliente em \MetadataResolverClient\bin ou \SvcutilClient\bin. A atividade do cliente é exibida no aplicativo do console do cliente.

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

  4. Remova os certificados executando Cleanup.bat quando tiver terminado de usar a amostra. Outros exemplos de segurança usam os mesmos certificados.

Para executar a amostra entre computadores

  1. No servidor, execute setup.bat service. A execução de setup.bat com o argumento service cria um certificado de serviço com o nome de domínio totalmente qualificado do computador e exporta o certificado de serviço para um arquivo chamado Service.cer.

  2. No servidor, edite Web.config para refletir o novo nome do certificado. Ou seja, altere o atributo findValue no elemento <serviceCertificate> para o nome de domínio totalmente qualificado do computador.

  3. Copie o arquivo Service.cer do diretório de serviço para o diretório do cliente no computador cliente.

  4. No cliente, execute setup.bat client. A execução de setup.bat com o argumento client cria um certificado de cliente chamado Client.com e exporta o certificado do cliente para um arquivo chamado Client.cer.

  5. No arquivo App.config do MetadataResolverClient no computador cliente, altere o valor do endereço do ponto de extremidade de mex para que corresponda ao novo endereço do seu serviço. Você faz isso substituindo localhost pelo nome de domínio totalmente qualificado do servidor. Altere também a ocorrência de "localhost" no arquivo metadataResolverClient.cs para o novo nome do certificado de serviço (o nome de domínio totalmente qualificado do servidor). Faça a mesma coisa para o App.config do projeto SvcutilClient.

  6. Copie o arquivo Client.cer do diretório do cliente para o diretório de serviço no servidor.

  7. No cliente, execute ImportServiceCert.bat. Isso importará o certificado de serviço do arquivo Service.cer para o repositório CurrentUser - TrustedPeople.

  8. No servidor, execute ImportClientCert.bat. Isso importará o certificado do cliente do arquivo Client.cer para o repositório LocalMachine - TrustedPeople.

  9. No computador de serviço, crie o projeto de serviço no Visual Studio e selecione a página de ajuda em um navegador da Web para verificar se ele está em execução.

  10. No computador cliente, execute o MetadataResolverClient ou o SvcutilClient do VS.

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

Para fazer uma limpeza após o exemplo

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

    Observação

    Esse script não remove os certificados de serviço em um cliente na execução dessa amostra em vários computadores. Se você tiver executado amostras do WCF (Windows Communication Foundation) que usam certificados em computadores, lembre-se de limpar os certificados de serviço que foram instalados no repositório CurrentUser - TrustedPeople. Para fazer isso, use o seguinte comando: certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name>. Por exemplo: certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com.