共用方式為


訊息安全性匿名

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

注意

此範例的安裝程序與建置指示位於本主題的結尾。

這個範例會將新作業新增至計算機介面,該介面會在用戶端未通過驗證時傳回 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>

用於服務驗證的認證會指定於<行為>中。 伺服器憑證中包含的 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="http://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
    

注意

如果您使用的是非美式英文版的 Windows,則必須編輯 Setup.bat 檔案,並以適用您所在地區的對等帳戶取代 NT AUTHORITY\NETWORK SERVICE 帳戶名稱。

若要安裝、建置及執行範例

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

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

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

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

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

    注意

    Setup 批次檔依設計可從 Visual Studio 的開發人員命令提示字元執行。 它要求 path 環境變數指向安裝 SDK 的目錄。 這個環境變數是自動在 Visual Studio 開發人員命令提示字元中設定。

  3. 輸入位址 http://localhost/servicemodelsamples/service.svc 以驗證是否可使用瀏覽器存取服務。

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

  5. 如果用戶端和服務無法通訊,請參閱 WCF 範例的疑難排解提示

若要跨電腦執行範例

  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>findValue 屬性中),這個名稱與電腦完整網域的名稱相同。

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

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

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

  10. 在用戶端電腦上,從命令提示字元啟動 Client.exe。 如果用戶端和服務無法通訊,請參閱 WCF 範例的疑難排解提示

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

  • 當您完成執行範例後,請執行範例資料夾中的 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.