覆寫服務的身分識別以進行驗證

一般來說,您不需要在服務上設定身分識別,因為選擇用戶端認證類型,即表示服務中繼資料中公開的身分識別類型。 例如,下列組態程式碼會使用 <wsHttpBinding> 元素,並將 clientCredentialType 屬性設定為 Windows。

下列 Web 服務描述語言 (WSDL) 片段會顯示端點先前定義的身分識別。 這個範例會在特定的使用者帳戶 (username@contoso.com) 之下,以自我裝載服務的形式執行服務;因此,使用者主要名稱 (UPN) 身分識別就會包含帳戶名稱。 UPN 在 Windows 網域中也稱為使用者登入名稱。

如需示範身分識別設定的範例應用程式,請參閱服務身分識別範例。 如需服務身分識別的詳細資訊,請參閱服務身分識別與驗證

Kerberos 驗證和身分識別

根據預設,當服務設為使用 Windows 認證時,包含 <userPrincipalName><servicePrincipalName> 元素的 <identity> 元素會在 WSDL 中產生。 如果服務是在 LocalSystemLocalServiceNetworkService 帳戶之下執行,則預設會以 host/<hostname> 格式產生服務主要名稱 (Service Principal Name,SPN),因為這些帳戶都可存取電腦的 SPN 資料。 如果是在不同的帳戶之下執行服務,則 Windows Communication Foundation (WCF) 會以 <username>@<domainName> 的格式產生 UPN。 這種情況發生的原因是 Kerberos 驗證需要對用戶端提供 UPN 或 SPN,才能驗證服務。

您也可以使用 Setspn 工具,以服務的帳戶在網域中登錄其他 SPN。 您接著就可以使用 SPN 做為服務的身分識別。 如需該工具的詳細資訊,請參閱 Setspn 概觀

注意

若不進行交涉而使用 Windows 認證類型,服務的使用者帳戶必須可以存取透過 Active Directory 網域登錄的 SPN。 您可以透過下列方式這樣做:

  • 使用 NetworkService 或 LocalSystem 帳戶執行服務。 因為這些帳戶均可存取電腦加入 Active Directory 網域時所建立的電腦 SPN,所以 WCF 會自動在服務中繼資料 (WSDL) 的服務端點內產生適當的 SPN 項目。

  • 使用任意的 Active Directory 網域帳戶來執行服務。 在這個情況下,請建立該網域帳戶的 SPN,您可使用 Setspn.exe 公用程式工具來進行。 一旦您建立了服務帳戶的 SPN,請設定 WCF 以透過其中繼資料 (WSDL) 將該 SPN 發行至服務的用戶端。 不論是透過應用程式組態檔或程式碼,均可設定公開端點的端點身分識別以完成此作業。

如需 SPN、Kerberos 通訊協定與 Active Directory 的詳細資訊,請參閱 Windows 的 Kerberos 技術資訊補充

SPN 或 UPN 等於空字串時

如果您設定 SPN 或 UPN 等於空字串,那麼會發生一些不同的狀況,依使用的安全性層級和驗證模式而定:

  • 如果您使用傳輸層級安全性,就會選擇 NT LanMan (NTLM) 驗證。

  • 如果您使用訊息層級安全性,驗證可能會失敗,依驗證模式而定:

  • 如果您正在使用 spnego 模式並且將 AllowNtlm 屬性設為 false,則驗證失敗。

  • 如果您正在使用 spnego 模式並且將 AllowNtlm 屬性設定為 true,則若 UPN 為空時驗證失敗,而若 SPN 為空時驗證成功。

  • 如果您正在直接使用 Kerberos (也就是「單次」),則驗證失敗。

在組態中使用 <identity> 元素

如果您在先前對 Certificate 顯示的繫結中變更用戶端認證類型,則產生的 WSDL 會包含 Base64 序列化 X.509 憑證做為身分識別值,如下列程式碼所示。 這是 Windows 以外所有用戶端認證類型的預設值。

您可以使用組態中的 <identity> 元素或在程式碼中設定身分識別,變更預設服務身分識別的值或變更身分識別的類型。 下列組態程式碼會以 contoso.com 這個值來設定網域名稱系統 (DNS) 身分識別。

以程式設計方式設定身分識別

您的服務不需要明確指定身分識別,因為 WCF 會自動決定。 不過,若必要,WCF 可讓您指定端點上的身分識別。 下列程式碼會新增具有特定 DNS 身分識別的新服務端點。

ServiceEndpoint ep = myServiceHost.AddServiceEndpoint(
                typeof(ICalculator),
                new WSHttpBinding(),
                String.Empty);
EndpointAddress myEndpointAdd = new EndpointAddress(new Uri("http://localhost:8088/calc"),
     EndpointIdentity.CreateDnsIdentity("contoso.com"));
ep.Address = myEndpointAdd;
Dim ep As ServiceEndpoint = myServiceHost.AddServiceEndpoint(GetType(ICalculator), New WSHttpBinding(), String.Empty)
Dim myEndpointAdd As New EndpointAddress(New Uri("http://localhost:8088/calc"), EndpointIdentity.CreateDnsIdentity("contoso.com"))
ep.Address = myEndpointAdd

另請參閱