Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En el ejemplo CustomMexEndpoint se muestra cómo implementar un servicio con un punto de conexión de metadatos seguro que usa uno de los enlaces de intercambio de no metadatos y cómo configurar serviceModel Metadata Utility Tool (Svcutil.exe) o clientes para capturar los metadatos de dicho punto de conexión de metadatos. Hay dos enlaces proporcionados por el sistema disponibles para exponer extremos de metadatos: mexHttpBinding y mexHttpsBinding. mexHttpBinding se usa para exponer un extremo de metadatos sobre HTTP de una manera no segura. mexHttpsBinding se utiliza para exponer de forma segura un punto de conexión de metadatos a través de HTTPS. En este ejemplo se muestra cómo exponer un punto de conexión de metadatos seguro mediante .WSHttpBinding Es posible que desee hacer esto cuando quiera cambiar la configuración de seguridad en la vinculación, pero no desee usar HTTPS. Si usa mexHttpsBinding el punto de conexión de metadatos será seguro, pero no hay ninguna manera de modificar la configuración de enlace.
Nota:
El procedimiento de instalación y las instrucciones de compilación de este ejemplo se encuentran al final de este tema.
Servicio
El servicio de este ejemplo tiene dos puntos de conexión. El punto de conexión de la aplicación sirve el contrato ICalculator
en WSHttpBinding
con ReliableSession
habilitados y seguridad Message
utilizando certificados. El punto de conexión de metadatos también usa WSHttpBinding
, con la misma configuración de seguridad, pero sin ReliableSession
. Esta es la configuración pertinente:
<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>
En muchos de los otros ejemplos, el punto de conexión de metadatos usa el valor predeterminado mexHttpBinding
, que no es seguro. Aquí los metadatos se protegen mediante WSHttpBinding
con Message
seguridad. Para que los clientes de metadatos recuperen estos metadatos, deben configurarse con un enlace coincidente. En este ejemplo se muestran dos clientes de este tipo.
El primer cliente usa Svcutil.exe para capturar los metadatos y generar código de cliente y configuración en tiempo de diseño. Dado que el servicio usa un enlace no predeterminado para los metadatos, la herramienta Svcutil.exe debe configurarse específicamente para que pueda obtener los metadatos del servicio mediante ese enlace.
El segundo cliente usa MetadataResolver
para capturar dinámicamente los metadatos de un contrato conocido y, a continuación, invocar operaciones en el cliente generado dinámicamente.
Cliente Svcutil
Al utilizar el enlace predeterminado para hospedar su punto de conexión IMetadataExchange
, puede ejecutar Svcutil.exe con la dirección de ese punto de conexión:
svcutil http://localhost/servicemodelsamples/service.svc/mex
y funciona. Pero en este ejemplo, el servidor usa un punto de conexión no predeterminado para hospedar los metadatos. Así que deben indicar a Svcutil.exe que utilice el enlace correcto. Esto se puede hacer mediante un archivo Svcutil.exe.config.
El archivo Svcutil.exe.config tiene el aspecto de un archivo de configuración de cliente normal. Los únicos aspectos inusuales son el nombre del punto de conexión de cliente y el contrato:
<endpoint name="http"
binding="wsHttpBinding"
bindingConfiguration="Binding1"
behaviorConfiguration="ClientCertificateBehavior"
contract="IMetadataExchange" />
El nombre del punto de conexión debe ser el nombre del esquema de la dirección donde se hospedan los metadatos y el contrato de punto de conexión debe ser IMetadataExchange
. Por lo tanto, cuando se ejecuta Svcutil.exe con una línea de comandos como la siguiente:
svcutil http://localhost/servicemodelsamples/service.svc/mex
busca el punto de conexión denominado "http" y determina el contrato IMetadataExchange
para configurar la vinculación y el comportamiento del intercambio de comunicación con el punto de conexión de metadatos. El resto del archivo Svcutil.exe.config del ejemplo especifica las credenciales de comportamiento y configuración de enlace para que coincidan con la configuración del servidor del punto de conexión de metadatos.
Para que Svcutil.exe pueda recoger la configuración en Svcutil.exe.config, Svcutil.exe debe estar en el mismo directorio que el archivo de configuración. Como resultado, debe copiar Svcutil.exe de su ubicación de instalación en el directorio que contiene el archivo Svcutil.exe.config. A continuación, ejecute el siguiente comando desde ese directorio:
.\svcutil.exe http://localhost/servicemodelsamples/service.svc/mex
El comienzo ". \" asegura que se ejecuta la copia de Svcutil.exe en este directorio (el que tiene el Svcutil.exe.config correspondiente).
Cliente MetadataResolver
Si el cliente conoce el contrato y cómo comunicarse con los metadatos durante la fase de diseño, puede descubrir dinámicamente el enlace y la dirección de los puntos de conexión de la aplicación mediante el MetadataResolver
. Este cliente de ejemplo demuestra esto mostrando cómo configurar el enlace y las credenciales utilizadas por MetadataResolver
creando y configurando MetadataExchangeClient
.
La misma información de enlace y certificado que apareció en Svcutil.exe.config se puede especificar de forma imperativa en 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");
Con la mexClient
configuración, podemos enumerar los contratos que nos interesan y usar MetadataResolver
para capturar una lista de puntos de conexión con esos 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 último, podemos usar la información de esos puntos de conexión para inicializar el enlace y la dirección de un ChannelFactory
usado para crear canales para comunicarse con los puntos de conexión de la aplicación.
ChannelFactory<ICalculator> cf = new ChannelFactory<ICalculator>(endpoint.Binding, endpoint.Address);
El punto clave de este cliente de ejemplo es demostrar que, si usa MetadataResolver
y debe especificar enlaces personalizados o comportamientos para la comunicación de intercambio de metadatos, puede usar un MetadataExchangeClient
para especificar esa configuración personalizada.
Para instalar y compilar el ejemplo
Asegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.
Para compilar la solución, siga las instrucciones que se indican en Compilación de los ejemplos de Windows Communication Foundation.
Para ejecutar el ejemplo en la misma máquina
Ejecute Setup.bat desde la carpeta de instalación de ejemplo. Esto instala todos los certificados necesarios para ejecutar el ejemplo. Tenga en cuenta que Setup.bat usa la herramienta FindPrivateKey.exe, que se instala ejecutando setupCertTool.bat en el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.
Ejecute la aplicación cliente desde \MetadataResolverClient\bin o \SvcutilClient\bin. La actividad de cliente se muestra en la aplicación de consola cliente.
Si el cliente y el servicio no pueden comunicarse, consulte Sugerencias de solución de problemas para ejemplos de WCF.
Quite los certificados ejecutando Cleanup.bat cuando haya terminado con el ejemplo. Otros ejemplos de seguridad usan los mismos certificados.
Para ejecutar el ejemplo en varias máquinas
En el servidor, ejecute
setup.bat service
. La ejecuciónsetup.bat
con elservice
argumento crea un certificado de servicio con el nombre de dominio completo de la máquina y exporta el certificado de servicio a un archivo denominado Service.cer.En el servidor, edite Web.config para reflejar el nuevo nombre del certificado. Es decir, cambie el atributo
findValue
en el elemento <serviceCertificate> al nombre de dominio completo de la máquina.Copie el archivo Service.cer del directorio de servicio en el directorio cliente del equipo cliente.
En el cliente, ejecute
setup.bat client
. La ejecuciónsetup.bat
con elclient
argumento crea un certificado de cliente denominado Client.com y exporta el certificado de cliente a un archivo denominado Client.cer.En el archivo App.config de
MetadataResolverClient
en el equipo cliente, cambie el valor de la dirección del extremo mex para que coincida con la nueva dirección de su servicio. Para ello, reemplace localhost por el nombre de dominio completo del servidor. Cambie también la aparición de "localhost" en el archivo metadataResolverClient.cs al nuevo nombre de certificado de servicio (el nombre de dominio completo del servidor). Haga lo mismo para App.config en el proyecto SvcutilClient.Copie el archivo Client.cer del directorio cliente en el directorio de servicio del servidor.
En el cliente, ejecute
ImportServiceCert.bat
. Así se importa el certificado del servicio del archivo Service.cer en el almacén CurrentUser - TrustedPeople.En el servidor, ejecute
ImportClientCert.bat
. De esta manera se importa el certificado de cliente del archivo Client.cer en el almacén LocalMachine - TrustedPeople.En el equipo de servicio, compile el proyecto de servicio en Visual Studio y seleccione la página de ayuda en un explorador web para comprobar que se está ejecutando.
En el equipo cliente, ejecute MetadataResolverClient o SvcutilClient desde VS.
- Si el cliente y el servicio no pueden comunicarse, consulte Sugerencias de solución de problemas para ejemplos de WCF.
Para limpiar después de la muestra.
Ejecute Cleanup.bat en la carpeta samples una vez que haya terminado de ejecutar el ejemplo.
Nota:
Este script no quita certificados de servicio en un cliente al ejecutar este ejemplo entre máquinas. Si ha ejecutado ejemplos de Windows Communication Foundation (WCF) que usan certificados entre máquinas, asegúrese de borrar los certificados de servicio que se han instalado en el almacén CurrentUser - TrustedPeople. Para ello, use el siguiente comando:
certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name>
. Por ejemplo:certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com
.