CustomMexEndpoint 範例示範如何使用其中一個非元數據交換系結的安全元數據端點來實作服務,以及如何設定 ServiceModel 元數據公用程式工具 (Svcutil.exe) 或用戶端從這類元數據端點擷取元數據。 有兩個系統提供的系結可用來公開元數據端點:mex HttpBinding 和 mexHttpsBinding。 mex HttpBinding 是用來以不安全的方式透過 HTTP 公開元數據端點。 mexHttpsBinding 是用來以安全的方式透過 HTTPS 公開元數據端點。 此範例說明如何使用 公開安全的元數據端點 WSHttpBinding。 當您想要變更系結上的安全性設定,但不想使用 HTTPS 時,您會想要這麼做。 如果您使用 mexHttpsBinding,則元數據端點會很安全,但無法修改系結設定。
備註
此範例的安裝程式和建置指示位於本主題結尾。
服務
此範例中的服務有兩個端點。 應用程式端點在ICalculator上使用憑證提供WSHttpBinding合約,並啟用ReliableSession和Message安全性。 元資料端點也會使用相同的 WSHttpBinding安全性設定,但沒有 ReliableSession。 以下是相關的組態:
<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>
在許多其他範例中,元數據端點會使用預設 mexHttpBinding,這是不安全的。 在這裡,元數據會使用 WSHttpBinding 搭配 Message 安全性來保護。 為了讓元數據用戶端擷取此元數據,它們必須設定成相符的系結。 此範例示範兩個這類用戶端。
第一個用戶端會使用 Svcutil.exe 來擷取元數據,並在設計時間產生用戶端程式代碼和組態。 因為服務對元數據使用非預設系結,所以必須特別設定 Svcutil.exe 工具,才能使用該系結從服務取得元數據。
第二個用戶端會使用 MetadataResolver 來動態擷取已知合約的元數據,然後在動態產生的用戶端上叫用作業。
Svcutil 用戶端
使用預設系結來裝載 IMetadataExchange 端點時,您可以使用該端點的位址來執行 Svcutil.exe:
svcutil http://localhost/servicemodelsamples/service.svc/mex
而且它運作正常。 但在此範例中,伺服器會使用非預設端點來裝載元數據。 因此,必須指示 Svcutil.exe 使用正確的系結。 這可以使用 Svcutil.exe.config 檔案來完成。
Svcutil.exe.config 檔案看起來像一般用戶端組態檔。 唯一不尋常的層面是用戶端端點名稱和合約:
<endpoint name="http"
binding="wsHttpBinding"
bindingConfiguration="Binding1"
behaviorConfiguration="ClientCertificateBehavior"
contract="IMetadataExchange" />
端點名稱必須是裝載元數據之位址設定的名稱,而且端點合約必須是 IMetadataExchange。 因此,當 Svcutil.exe 以命令行執行時,如下所示:
svcutil http://localhost/servicemodelsamples/service.svc/mex
它會尋找名為 「HTTP」 的端點,以及合約 IMetadataExchange ,以設定與元數據端點通訊交換的系結和行為。 範例中其餘 Svcutil.exe.config 檔案會指定系結組態和行為認證,以符合伺服器元數據端點的組態。
為了讓 Svcutil.exe 在 Svcutil.exe.config中挑選組態,Svcutil.exe 必須與組態檔位於相同的目錄中。 因此,您必須將 Svcutil.exe 從其安裝位置複製到包含 Svcutil.exe.config 檔案的目錄。 然後從該目錄執行下列命令:
.\svcutil.exe http://localhost/servicemodelsamples/service.svc/mex
前置 “.\” 可確保執行此目錄中 Svcutil.exe 複本(具有對應 Svcutil.exe.config的複本。
MetadataResolver 用戶端
如果用戶端知道合約以及如何在設計時與中繼資料進行互動,用戶端可以動態地找出應用程式端點的系結和位址,使用MetadataResolver。 此範例用戶端展示了如何藉由建立和配置MetadataResolver來設定MetadataExchangeClient所用的綁定和認證。
您可以在 MetadataExchangeClient 上明確指定與在 Svcutil.exe.config 中出現的相同的系結和憑證資訊。
// 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");
透過設定 mexClient ,我們可以列舉感興趣的合約,並使用 MetadataResolver 來擷取具有這些合約的端點清單:
// 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);
最後,我們可以使用這些端點的資訊來初始化ChannelFactory,以設定與應用程式端點通訊的通道所需的系結和位址。
ChannelFactory<ICalculator> cf = new ChannelFactory<ICalculator>(endpoint.Binding, endpoint.Address);
此範例客戶端的關鍵點是示範,如果您使用 MetadataResolver,而且您必須指定元數據交換通訊的自定義系結或行為,您可以使用 MetadataExchangeClient 來指定這些自定義設定。
若要設定和建置範例
請確定您已針對 Windows Communication Foundation 範例 執行One-Time 安裝程式。
若要建置解決方案,請遵循 建置 Windows Communication Foundation 範例中的指示。
在同一台電腦上運行範例
從範例安裝資料夾執行 Setup.bat。 這會安裝執行範例所需的所有憑證。 請注意,Setup.bat 會使用 FindPrivateKey.exe 工具,此工具是藉由從 Windows Communication Foundation 範例One-Time 安裝程式執行 setupCertTool.bat 來安裝。
從 \MetadataResolverClient\bin 或 \SvcutilClient\bin 執行用戶端應用程式。 用戶端活動會顯示在用戶端主控台應用程式上。
如果客戶端和服務無法通訊,請參閱 WCF 範例 的疑難解答秘訣。
當您完成範例時,請執行 Cleanup.bat 來移除憑證。 其他安全性範例使用相同的憑證。
要在多台電腦上執行範例
在伺服器上,執行
setup.bat service。 使用setup.bat和service參數執行會建立具有計算機完整域名的服務憑證,並將服務憑證匯出至名為 Service.cer 的檔案。在伺服器上,編輯 Web.config 以反映新的憑證名稱。 也就是說,將
findValueserviceCertificate< 元素中的> 屬性變更為機器的完整域名稱。將Service.cer檔案從服務目錄複製到用戶端電腦上的客戶端目錄。
在用戶端上,執行
setup.bat client。 通過setup.bat並使用client參數執行這個指令,將會建立一個名為 Client.com 的用戶端憑證,並將該憑證匯出到一個名為 Client.cer 的檔案中。在用戶端電腦上的 App.config 檔案
MetadataResolverClient中,變更 mex 端點的位址值,以符合您服務的新位址。 您可以藉由將localhost取代為伺服器的完整功能變數名稱來執行此動作。 此外,將 metadataResolverClient.cs 檔案中的「localhost」 替換為新的服務憑證名稱(伺服器的完整域名)。 針對 SvcutilClient 專案的 App.config 執行相同動作。將Client.cer檔案從客戶端目錄複製到伺服器上的服務目錄。
在用戶端上,執行
ImportServiceCert.bat。 這會將服務憑證從 Service.cer 檔案匯入 CurrentUser - TrustedPeople 存放區。在伺服器上執行
ImportClientCert.bat,這會從 Client.cer 檔案將用戶端憑證匯入 LocalMachine - TrustedPeople 存放區。在服務機器上,在 Visual Studio 中建置服務專案,然後在網頁瀏覽器中選取說明頁面,以確認它正在執行中。
在用戶端計算機上,從 VS 執行 MetadataResolverClient 或 SvcutilClient。
- 如果客戶端和服務無法通訊,請參閱 WCF 範例 的疑難解答秘訣。
在範例之後清除
在您完成執行範例之後,請在samples資料夾中執行 Cleanup.bat。
備註
在跨機器執行此範例時,此腳本不會移除用戶端上的服務憑證。 如果您已執行跨計算機使用憑證的 Windows Communication Foundation (WCF) 範例,請務必清除已在 CurrentUser - TrustedPeople 存放區中安裝的服務憑證。 若要這樣做,請使用下列命令:
certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name>。 例如:certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com。