現在我們討論TransportCredentialOnly安全模式下的安全配置,首先在設定檔中添加如代碼清單11-84所示的配置節,配置windows驗證。Windows憑據認證是基於Windows組賬戶或者域賬戶進行認證的方式。在這種認證方式下,用戶端進程啟動並執行Window帳號對應的Windows憑證被自動作為調用服務的用戶端憑證,所以無需顯示指定具體的Windiws憑證。如果需要另一個Windows帳號的名義調用服務,用戶端就需要通知指定Windows帳號和密碼的方式顯式地進行用戶端Windows憑證的設定。Windows憑證在WCF通過類型WindowsClientCredential表示。真正的憑證最終儲存在類型為NetworkCredential的ClientCredential屬性中。通過該屬性,你可以指定Windows憑證的網域名稱、使用者名稱和密碼。
註:
TransportCredentialOnly安全模式是明文傳輸,這裡是為了查看通訊細節才採用這種方式,實際情境不推薦使用。
代碼清單11-84 配置windows驗證
1: <bindings>
2:
3: <basicHttpBinding>
4:
5: <binding name="basicBindingConf">
6:
7: <security mode=" TransportCredentialOnly" >
8:
9: <transport clientCredentialType="Windows">
10:
11: </transport>
12:
13: </security>
14:
15: </binding>
16:
17: </basicHttpBinding>
18:
19: </bindings>
看清單11-84,通過<ecurity mode=" TransportCredentialOnly ">”設定安全模式為TransportCredentialOnly,然後通過設定<transport clientCredentialType="Windows">設定用戶端憑據類型為Windows。此外我們需要佈建網站的認證模式為Windows,設定方式如代碼清單11-85。
代碼清單11-85 佈建網站的認證模式為Windows
1: <system.web>
2:
3: <authentication mode="Windows"></authentication>
4:
5: </system.web>
服務端更改完畢之後,還有確保IIS開啟了Windows認證。最後我們更新用戶端的服務引用,右鍵服務引用,然後單擊“更新服務引用”,我們會看到11-36所示的彈出框。
圖11-36 更新服用引用需要驗證憑據
輸入驗證資訊之後,用戶端的安全配置更新為代碼清單11-86所示的內容。
代碼清單11-86 windows認證時用戶端安全配置
1: <security mode="TransportCredentialOnly">
2:
3: <transport clientCredentialType="Windows" proxyCredentialType="None"
4:
5: alm="" />
6:
7: <message clientCredentialType="UserName" algorithmSuite="Default" />
8:
9: </security>
我們傳遞一個錯誤的使用者賬戶資訊,啟動測試網站,會得到11-37所示的錯誤資訊。
圖11-37 windows身分識別驗證未通過
圖11-37所示的錯誤資訊是因為用戶端未提供正確的身分識別驗證資訊導致的。實際上用戶端和服務端經過了三次協商,最後一次的服務端響應資訊如代碼清單11-87。
代碼清單11-87 驗證失敗的服務端響應資訊頭
HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Sat, 25 Jun 2011 10:44:49 GMT
Content-Length: 6331
Proxy-Support: Session-Based-Authentication
返回401許可權驗證失敗的資訊,驗證標題為Negotiate和NTLM。
Negotiate 身分識別驗證協議包是 Windows 中的一個安全性支援提供者 (SSP),它提供身分識別驗證和加密。它的作用是基於用戶端電腦和伺服器上支援的協議協商要用於身分識別驗證請求的身分識別驗證協議。在 Windows 7 和 Windows Server 2008 R2 之前的 Windows 版本中,Negotiate 包支援 NTLM 和 Kerberos。對於 Windows 7 和 Windows Server 2008 R2,已經對 Negotiate 包進行了更新,以支援更多 SSP。
出現上面的錯誤資訊實際上是因為我的IIS的Windows驗證預設提供成為Negotiate和NTLM,當然我們還可以添加Kerberos驗證方式。
那個如何在用戶端附加Windows身分識別驗證資訊呢?代碼清單11-88是修改後的用戶端代碼。
代碼清單11-88 設定windows賬戶資訊
public ActionResult Index()
{
client.ClientCredentials.Windows.ClientCredential.Domain = "corp.beisen.com";
client.ClientCredentials.Windows.ClientCredential.UserName = "yangwenhai";
client.ClientCredentials.Windows.ClientCredential.Password = "xuan$%^hun456";
string helloString = client.GetHello();
ViewData["Message"] = helloString;
return View();
}
在代碼清單11-88中,我們通過設定client.ClientCredentials.Windows.ClientCredential的Domain屬性來設定域資訊,通過UserName屬性設定使用者名稱,通過Password屬性設定密碼。
說明:
正常情況下,用戶端和伺服器在同一個域環境中,是不需要傳遞使用者名稱和密碼的。
運行結果11-38。
圖11-38 Windows驗證