訊息安全性匿名

訊息安全性匿名範例會示範如何實作 Windows Communication Foundation (WCF) 應用程式,這個應用程式所使用的訊息層級安全性並不會透過用戶端驗證,而是要求以伺服器的 X.509 憑證進行伺服器驗證。 用戶端與伺服器之間的所有應用程式訊息都會經過簽署及加密。 這個範例是以 WSHttpBinding 範例為基礎。 這個範例是由用戶端主控台程式 (.exe) 和網際網路資訊服務 (IIS) 所裝載的服務程式庫 (.dll) 所組成。 服務會實作定義要求-回覆通訊模式的合約。

ms752231.note(zh-tw,VS.100).gif注意:
此範例的安裝程序與建置指示位於本主題的結尾。

這個範例會將新作業新增至計算機介面,該介面會在用戶端未通過驗證時傳回 True

public class CalculatorService : ICalculator
{
    public bool IsCallerAnonymous()
    {
        // ServiceSecurityContext.IsAnonymous returns true if the caller is not authenticated.
        return ServiceSecurityContext.Current.IsAnonymous;
    }
    ...
}

此服務會公開 (Expose) 單一的端點來與已使用組態檔 Web.config 定義之服務進行通訊。 端點是由位址、繫結及合約所組成。 此繫結是使用指定的 wsHttpBinding 繫結所設定的。 wsHttpBinding 繫結的預設安全性模式為 MessageclientCredentialType 屬性會設定為 None

<system.serviceModel>

  <protocolMapping>
    <add scheme="http" binding="wsHttpBinding" />
  </protocolMapping>

  <bindings>
    <wsHttpBinding>
     <!-- 
     <!--This configuration defines the security mode as Message and-->
     <!--the clientCredentialType as None. This mode provides -- >
     <!--server authentication only using the service certificate.-->
      
     <binding>
       <security mode="Message">
         <message clientCredentialType="None" />
       </security>
     </binding>
    </wsHttpBinding>
  </bindings>
  ...
</system.serviceModel>

用於服務驗證的認證會指定於 behavior Element中。 伺服器憑證中包含的 SubjectName 值必須與 findValue 屬性的指定值相同,如下列範例程式碼所示。

<behaviors>
  <serviceBehaviors>
    <behavior>
      <!-- 
    The serviceCredentials behavior allows you to define a service certificate.
    A service certificate is used by a client to authenticate the service and provide message protection.
    This configuration references the "localhost" certificate installed during the setup instructions.
    -->
      <serviceCredentials>
        <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
      </serviceCredentials>
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="False" />
    </behavior>
  </serviceBehaviors>
</behaviors>

用戶端端點組態是由服務端點的絕對位址、繫結及合約所組成。 wsHttpBinding 繫結的用戶端安全性模式為 MessageclientCredentialType 屬性會設定為 None

<system.serviceModel>
  <client>
    <endpoint name=""
             address="https://localhost/servicemodelsamples/service.svc" 
             binding="wsHttpBinding" 
             behaviorConfiguration="ClientCredentialsBehavior"
             bindingConfiguration="Binding1" 
             contract="Microsoft.ServiceModel.Samples.ICalculator" />
  </client>

  <bindings>
    <wsHttpBinding>
      <!--This configuration defines the security mode as -->
      <!--Message and the clientCredentialType as None. -->
      <binding name="Binding1">
        <security mode = "Message">
          <message clientCredentialType="None"/>
        </security>
      </binding>
    </wsHttpBinding>
  </bindings> 
  ...
</system.serviceModel>

此範例會將 CertificateValidationMode 設定為 PeerOrChainTrust 以驗證服務的憑證。 此項作業會在用戶端 App.config 檔的 behaviors 區段中完成。 這表示如果憑證位在使用者之受信任人的存放區,則此憑證就受到信任,而不會執行驗證憑證的簽發者鏈結。 範例中是基於方便而使用這項設定,這樣便能夠在不需要憑證授權單位 (CA) 發出之憑證的情況下執行此範例。 這個設定的安全性比預設值 (ChainTrust) 低。 在實際執行程式碼 (Production Code) 中使用 PeerOrChainTrust 之前,應該要謹慎考量這項設定。

用戶端實作會新增 IsCallerAnonymous 方法的呼叫,在其他方面則與 WSHttpBinding 範例相同。

// Create a client with a client endpoint configuration.
CalculatorClient client = new CalculatorClient();

// Call the GetCallerIdentity operation.
Console.WriteLine("IsCallerAnonymous returned: {0}", client.IsCallerAnonymous());

// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

...

//Closing the client gracefully closes the connection and cleans up resources.
client.Close();

Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();
 

當您執行範例時,作業要求和回應會顯示在用戶端主控台視窗中。 在用戶端視窗中按下 ENTER 鍵,即可關閉用戶端。

IsCallerAnonymous returned: True
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 批次檔可讓您使用相關的憑證設定伺服器,以執行需要憑證安全性的裝載應用程式。 此批次檔可以在兩種模式中執行。 若要在單一電腦模式中執行此批次檔,請在命令列中輸入 setup.bat。 若要在服務模式中執行此批次檔,請輸入 setup.bat service。 請在跨電腦執行範例時使用這個模式。 如需詳細資訊,請參閱本主題結尾的安裝程序。

下面會提供批次檔之不同區段的簡短概觀。

  • 建立伺服器憑證。

    下列 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 存放區中。 如果使用 service 引數執行安裝批次檔 (例如 setup.bat service),%SERVER_NAME% 就會包含電腦的完整網域名稱。 否則,預設為 localhost。

  • 將伺服器憑證安裝至用戶端的受信任憑證存放區中。

    下列程式行會將伺服器憑證複製到用戶端受信任人的存放區中。 這是必要步驟,因為用戶端系統並未隱含信任 Makecert.exe 產生的憑證。 如果您已經有一個以用戶端信任的根憑證 (例如 Microsoft 所發行的憑證) 為基礎的憑證,就不需要這個將伺服器憑證填入用戶端憑證的步驟。

    certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
    
  • 授與憑證私密金鑰的權限。

    在 Setup.bat 批次檔中的下列程式行,會讓儲存在 LocalMachine 存放區的伺服器憑證可由 ASP.NET 背景工作處理序帳戶存取。

    echo ************
    echo setting privileges on server certificates
    echo ************
    for /F "delims=" %%i in ('"%MSSDK%\bin\FindPrivateKey.exe" My LocalMachine -n CN^=%SERVER_NAME% -a') do set PRIVATE_KEY_FILE=%%i set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE
    (ver | findstr "5.1") && set WP_ACCOUNT=%COMPUTERNAME%\ASPNET
    echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G "%WP_ACCOUNT%":R
    iisreset
    
ms752231.note(zh-tw,VS.100).gif注意:
如果您使用的是非美式 英文版的 Windows,就必須編輯 Setup.bat 檔案,並以適用您所在地區的對等帳戶取代 NT AUTHORITY\NETWORK SERVICE 帳戶名稱。

若要設定、建置及執行範例

  1. 請確定您已執行 Windows Communication Foundation 範例的單次安裝程序

  2. 若要建置方案的 C# 或 Visual Basic .NET 版本,請遵循建置 Windows Communication Foundation 範例中的指示。

若要在同一部電腦上執行範例

  1. 確認路徑中包含 Makecert.exe 和 FindPrivateKey.exe 所在的資料夾。

  2. 在使用系統管理員權限執行的 Visual Studio 命令提示字元中,執行範例安裝資料夾中的 Setup.bat。 這會安裝執行範例所需的所有憑證。

    ms752231.note(zh-tw,VS.100).gif注意:
    安裝批次檔是設計用來從 Visual Studio 2010 命令提示字元執行。 它要求 path 環境變數指向安裝 SDK 的目錄。 這個環境變數是自動在 Visual Studio 2010 命令提示字元中設定。

  3. 在瀏覽器輸入位址 https://localhost/servicemodelsamples/service.svc 來確認服務存取。

  4. 從 \client\bin 啟動 Client.exe。 用戶端活動會顯示在用戶端主控台應用程式上。

  5. 如果用戶端和服務無法通訊,請參閱Troubleshooting Tips

若要跨電腦執行範例

  1. 在服務電腦上建立目錄。 使用 Internet Information Services (IIS) 管理工具,為這個目錄建立名為 servicemodelsamples 的虛擬應用程式。

  2. 將 \inetpub\wwwroot\servicemodelsamples 中的服務程式檔複製至服務電腦上的虛擬目錄中。 確定複製 \bin 子目錄中的檔案。 同時,將 Setup.bat 和 Cleanup.bat 檔案複製到服務電腦中。

  3. 在用戶端電腦上為用戶端二進位碼檔案建立一個目錄。

  4. 將用戶端程式檔複製到用戶端電腦上的用戶端目錄。 同時,將 Setup.bat、Cleanup.bat 和 ImportServiceCert.bat 檔案複製到用戶端。

  5. 在伺服器上,於使用系統管理員權限開啟的 Visual Studio 命令提示字元中,執行 setup.bat service。 使用 service 引數執行 setup.bat 就會建立具有電腦完整網域名稱的服務憑證,並且將服務憑證匯出為名為 Service.cer 的檔案。

  6. 編輯 Web.config 以反映新的憑證名稱 (在 serviceCertificate element of serviceCredentialsfindValue 屬性中),這個名稱與電腦的完整網域名稱相同。

  7. 從服務目錄中將 Service.cer 檔案複製至用戶端電腦上的用戶端目錄。

  8. 在用戶端電腦上的 Client.exe.config 檔案中,變更端點的位址值以符合服務的新位址。

  9. 在用戶端上,於使用系統管理員權限開啟的 Visual Studio 命令提示字元中,執行 ImportServiceCert.bat。 這樣會將服務憑證從 Service.cer 檔案匯入至 CurrentUser - TrustedPeople 存放區中。

  10. 在用戶端電腦上,從命令提示字元啟動 Client.exe。 如果用戶端和服務無法通訊,請參閱Troubleshooting Tips

若要在使用範例之後進行清除

  • 當您完成執行範例後,請執行範例資料夾中的 Cleanup.bat。
ms752231.note(zh-tw,VS.100).gif注意:
跨電腦執行此範例時,這個指令碼不會移除用戶端上的服務憑證。 如果您已執行跨電腦使用憑證的 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.