訊息安全性憑證
MessageSecurity 範例 示範如何為用戶端實作使用 WS-Security 搭配 X.509 v3 憑證驗證的應用程式,並使用伺服器的 X.509 v3 憑證進行伺服器驗證。 此範例會使用預設設定,讓用戶端與伺服器之間的所有應用程式訊息都經過簽署和加密。 此範例是以 WSHttpBinding 為基礎,由 Internet Information Services (IIS) 所裝載的用戶端控制台程式和服務連結庫所組成。 服務會實作定義要求-回復通訊模式的合約。
注意
此範例的安裝程式和建置指示位於本主題結尾。
此範例示範如何使用組態來控制驗證,以及如何從安全性內容取得呼叫端的身分識別,如下列範例程式代碼所示。
public class CalculatorService : ICalculator
{
public string GetCallerIdentity()
{
// The client certificate is not mapped to a Windows identity by default.
// ServiceSecurityContext.PrimaryIdentity is populated based on the information
// in the certificate that the client used to authenticate itself to the service.
return ServiceSecurityContext.Current.PrimaryIdentity.Name;
}
...
}
服務會公開兩個端點:一個用於與服務通訊,另一個用於透過組態檔(Web.config)定義的 WS-MetadataExchange 通訊協定來公開服務的 WSDL 文件。 端點是由位址、系結和合約所組成。 系結是使用標準 <wsHttpBinding> 項目來設定,預設為使用訊息安全性。 此範例會將 clientCredentialType
屬性設定為憑證,以要求客戶端驗證。
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding"/>
</protocolMapping>
<bindings>
<wsHttpBinding>
<!--
This configuration defines the security mode as Message and
the clientCredentialType as Certificate.
-->
<binding>
<security mode ="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
<!--
The serviceCredentials behavior allows one to define a service certificate.
A service certificate is used by the service to authenticate itself to its clients and to provide message protection.
This configuration references the "localhost" certificate installed during the setup instructions.
-->
<serviceCredentials>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
<clientCertificate>
<!--
Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
is in the user's Trusted People store, then it will be trusted without performing a
validation of the certificate's issuer chain. This setting is used here for convenience so that the
sample can be run without having to have certificates issued by a certification authority (CA).
This setting is less secure than the default, ChainTrust. The security implications of this
setting should be carefully considered before using PeerOrChainTrust in production code.
-->
<authentication certificateValidationMode="PeerOrChainTrust" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
行為指定客戶端在驗證服務時使用的服務憑證。 伺服器證書主體名稱是在 <serviceCredentials> 元素的 findValue
屬性中指定。
<!--For debugging purposes, set the includeExceptionDetailInFaults attribute to true.-->
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
<!--
The serviceCredentials behavior allows one to define a service certificate.
A service certificate is used by the service to authenticate itself to its clients and to provide message protection.
This configuration references the "localhost" certificate installed during the setup instructions.
-->
<serviceCredentials>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
<clientCertificate>
<!--
Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
is in the user's Trusted People store, then it will be trusted without performing a
validation of the certificate's issuer chain. This setting is used here for convenience so that the
sample can be run without having to have certificates issued by a certification authority (CA).
This setting is less secure than the default, ChainTrust. The security implications of this
setting should be carefully considered before using PeerOrChainTrust in production code.
-->
<authentication certificateValidationMode="PeerOrChainTrust" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
用戶端端點組態是由服務端點、系結和合約的絕對位址所組成。 用戶端系結會設定適當的安全性模式和驗證模式。 在跨計算機案例中執行時,請確定服務端點位址會隨之變更。
<system.serviceModel>
<client>
<!-- Use a behavior to configure the client certificate to present to the service. -->
<endpoint address="http://localhost/servicemodelsamples/service.svc" binding="wsHttpBinding" bindingConfiguration="Binding1" behaviorConfiguration="ClientCertificateBehavior" contract="Microsoft.Samples.Certificate.ICalculator"/>
</client>
<bindings>
<wsHttpBinding>
<!--
This configuration defines the security mode as Message and
the clientCredentialType as Certificate.
-->
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
...
</system.serviceModel>
用戶端實作可以透過組態檔或程式代碼設定要使用的憑證。 下列範例示範如何設定要用於組態檔的憑證。
<system.serviceModel>
...
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<!--
The clientCredentials behavior allows one to define a certificate to present to a service.
A certificate is used by a client to authenticate itself to the service and provide message integrity.
This configuration references the "client.com" certificate installed during the setup instructions.
-->
<clientCredentials>
<clientCertificate findValue="client.com" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName"/>
<serviceCertificate>
<!--
Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
is in the user's Trusted People store, then it will be trusted without performing a
validation of the certificate's issuer chain. This setting is used here for convenience so that the
sample can be run without having to have certificates issued by a certificate authority (CA).
This setting is less secure than the default, ChainTrust. The security implications of this
setting should be carefully considered before using PeerOrChainTrust in production code.
-->
<authentication certificateValidationMode="PeerOrChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
下列範例示範如何在程式中呼叫服務。
// Create a client.
CalculatorClient client = new CalculatorClient();
// Call the GetCallerIdentity service operation.
Console.WriteLine(client.GetCallerIdentity());
...
//Closing the client gracefully closes the connection and cleans up resources.
client.Close();
當您執行範例時,作業要求和回應會顯示在用戶端控制台視窗中。 在客戶端視窗中按 ENTER 鍵以關閉用戶端。
CN=client.com
Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Press <ENTER> to terminate client.
訊息安全性範例隨附的 Setup.bat 批處理檔可讓您設定具有相關憑證的用戶端和伺服器,以執行需要憑證型安全性的託管應用程式。 批處理檔可以三種模式執行。 若要在 Visual Studio 開發人員命令提示字元中執行單一電腦模式,輸入 setup.bat;若要執行服務模式,輸入 setup.bat 服務;用戶端模式則輸入 setup.bat 用戶端。 在跨電腦執行範例時,請使用用戶端和伺服器模式。 如需詳細資訊,請參閱本主題結尾的安裝程式。 下列提供批處理檔不同區段的簡短概觀,以便修改它們以在適當的組態中執行:
建立客戶端憑證。
批處理檔中的下一行會建立客戶端憑證。 指定的用戶端名稱會用於所建立憑證的主體名稱。 憑證會儲存在
My
存放區,位於CurrentUser
存放位置。echo ************ echo making client cert echo ************ makecert.exe -sr CurrentUser -ss MY -a sha1 -n CN=%CLIENT_NAME% -sky exchange -pe
將客戶端憑證安裝到伺服器的受信任證書存儲中。
批處理檔中的下一行會將用戶端憑證複製到伺服器的 TrustedPeople 存放區,讓伺服器能夠做出相關的信任或無信任決策。 為了讓在 TrustedPeople 存放區中安裝的憑證受到 Windows Communication Foundation (WCF) 服務的信任,用戶端憑證驗證模式必須設定為
PeerOrChainTrust
或PeerTrust
。 請參閱先前的服務組態範例,以瞭解如何使用組態檔來完成這項作業。echo ************ echo copying client cert to server's LocalMachine store echo ************ certmgr.exe -add -r CurrentUser -s My -c -n %CLIENT_NAME% -r LocalMachine -s TrustedPeople
建立伺服器證書。
Setup.bat 批處理檔中的下列幾行會建立要使用的伺服器證書。
echo ************ echo Server cert setup starting echo %SERVER_NAME% echo ************ echo making server cert echo ************ makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
%SERVER_NAME% 變數會指定伺服器名稱。 憑證會儲存在LocalMachine存放區中。 如果 Setup.bat 批處理檔是以服務自變數執行(例如 setup.bat 服務),則 %SERVER_NAME% 包含計算機的完整功能變數名稱。 否則會預設為localhost。
將伺服器證書安裝到用戶端的受信任證書存儲中。
下列這一行會將伺服器證書複製到用戶端信任的人員存放區。 這是必要步驟,因為客戶端系統不會隱含信任 Makecert.exe 所產生的憑證。 如果您已經有依賴用戶端信任的根憑證的憑證,例如由 Microsoft 發行的憑證,則不需要將伺服器憑證填入用戶端憑證存儲中。
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
授與憑證私鑰的許可權。
Setup.bat 檔案中的下列幾行可讓 ASP.NET 背景工作進程帳戶存取 LocalMachine 存放區中的伺服器證書。
echo ************ echo setting privileges on server certificates echo ************ for /F "delims=" %%i in ('"%ProgramFiles%\ServiceModelSampleTools\FindPrivateKey.exe" My LocalMachine -n CN^=%SERVER_NAME% -a') do set PRIVATE_KEY_FILE=%%i set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE (ver | findstr /C:"5.1") && set WP_ACCOUNT=%COMPUTERNAME%\ASPNET echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G "%WP_ACCOUNT%":R iisreset
注意
如果您使用非美國英文版的 Windows,您必須編輯 Setup.bat 檔案,並將「NT AUTHORITY\NETWORK SERVICE」帳戶名稱替換為您地區相應的名稱。
注意事項
此批處理檔中所使用的工具位於 C:\Program Files\Microsoft Visual Studio 8\Common7\tools 或 C:\Program Files\Microsoft SDKs\Windows\v6.0\bin。 其中一個目錄必須位於您的系統路徑中。 如果您已安裝 Visual Studio,在路徑中取得此目錄最簡單的方式就是開啟 Visual Studio 的開發人員命令提示字元。 單擊 [開始],然後選取 [所有程式]、Visual Studio 2012[工具]。 此命令提示字元已設定適當的路徑。 否則,您必須手動將適當的目錄新增至您的路徑。
若要設定、建置和執行範例
請確定您已針對 Windows Communication Foundation 範例 執行One-Time 安裝程式。
若要建置解決方案的 C# 或 Visual Basic .NET 版本,請遵循建置 Windows Communication Foundation 範例 中中的指示。
在同一部電腦上執行這個範例
使用系統管理員許可權開啟 Visual Studio 的開發人員命令提示字元,然後從範例安裝資料夾執行 Setup.bat。 這會安裝執行範例所需的所有憑證。
注意
Setup.bat 批處理文件的設計目的是要從 Visual Studio 的開發人員命令提示字元執行。 它要求路徑環境變數指向安裝 SDK 的目錄。 此環境變數會自動在 Visual Studio 的開發人員命令提示字元中設定 (2010)。
使用瀏覽器輸入位址
http://localhost/servicemodelsamples/service.svc
,以確認可存取此服務。從 \client\bin 啟動 Client.exe。 用戶端活動會顯示在用戶端主控台應用程式上。
如果客戶端和服務無法通訊,請參閱 WCF 範例 的疑難解答秘訣。
在多台電腦上執行範例
在服務電腦上建立目錄。 使用 Internet Information Services (IIS) 管理工具,為此目錄建立名為 servicemodelsamples 的虛擬應用程式。
將服務程式檔案從 \inetpub\wwwroot\servicemodelsamples 複製到服務計算機上的虛擬目錄。 請確定您複製 \bin 子目錄中的檔案。 同時將 Setup.bat、Cleanup.bat和 ImportClientCert.bat 檔案複製到服務計算機。
在用戶端電腦上為用戶端二進位檔建立目錄。
將用戶端程式檔案複製到用戶端電腦上的客戶端目錄。 同時將 Setup.bat、Cleanup.bat和 ImportServiceCert.bat 檔案複製到用戶端。
在伺服器上,以系統管理員許可權在 Visual Studio 開發人員命令提示字元中執行 setup.bat 服務。 執行 setup.bat 並使用 服務 參數將會建立一個包含電腦全域域名的服務憑證,然後將該憑證匯出到名為 Service.cer 的檔案。
編輯 Web.config 以反映新憑證名稱(在 <serviceCertificate>的
findValue
屬性中),其與計算機的完整域名相同。將Service.cer檔案從服務目錄複製到用戶端電腦上的客戶端目錄。
在用戶端上,使用系統管理員權限在 Visual Studio 的開發人員命令提示字元中執行 setup.bat。 使用 用戶端 自變數執行 setup.bat 會建立名為 client.com 的客戶端憑證,並將用戶端憑證導出至名為 Client.cer 的檔案。
在用戶端電腦上的 Client.exe.config 檔案中,變更端點的位址值,以符合您服務的新位址。 將localhost替換為伺服器的完整網域名稱。
將Client.cer檔案從客戶端目錄複製到伺服器上的服務目錄。
在用戶端上,以系統管理許可權在 Visual Studio 的開發人員命令提示字元中執行 ImportServiceCert.bat。 這會將服務憑證從 Service.cer 檔案匯入 CurrentUser - TrustedPeople 存放區。
在伺服器上,以系統管理許可權在 Visual Studio 的開發人員命令提示字元中執行 ImportClientCert.bat。 這會將客戶端憑證從 Client.cer 檔案匯入 LocalMachine - TrustedPeople 存放區。
在用戶端電腦上,從命令提示字元窗口啟動 Client.exe。 如果客戶端和服務無法通訊,請參閱 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
。