覆寫服務的身分識別以進行驗證
一般來說,您不需要在服務上設定身分識別,因為選擇用戶端認證類型,即表示服務中繼資料中公開的身分識別類型。 例如,下列組態程式碼會使用 <wsHttpBinding> 元素,並將 clientCredentialType
屬性設定為 Windows。
下列 Web 服務描述語言 (WSDL) 片段會顯示端點先前定義的身分識別。 這個範例會在特定的使用者帳戶 (username@contoso.com
) 之下,以自我裝載服務的形式執行服務;因此,使用者主要名稱 (UPN) 身分識別就會包含帳戶名稱。 UPN 在 Windows 網域中也稱為使用者登入名稱。
如需示範身分識別設定的範例應用程式,請參閱服務身分識別範例。 如需服務身分識別的詳細資訊,請參閱服務身分識別與驗證。
Kerberos 驗證和身分識別
根據預設,當服務設為使用 Windows 認證時,包含 <userPrincipalName> 或 <servicePrincipalName> 元素的 <identity> 元素會在 WSDL 中產生。 如果服務是在 LocalSystem
、LocalService
或 NetworkService
帳戶之下執行,則預設會以 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