首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 安全實戰系列(四):WSHttpBinding Transport 安全模式完整指南與常見陷阱

     編輯:關於.NET

WSHttpBinding 概觀與測試基礎架構

WSHttpBinding 是 WCF 中最常用的 HTTP 綁定,預設實作 WS-Security 與 WS-* 協定,支援與任何相容服務互通。本系列採用統一服務合約與實作:

[ServiceContract(Namespace = "https://chnking.com")]
public interface IGetIdentity
{
    [OperationContract]
    string Get(string ClientIdentity);
}

public class GetIdentity : IGetIdentity
{
    public string Get(string ClientIdentity)
    {
        return "服務端Identity是'" + ServiceSecurityContext.Current.PrimaryIdentity.Name +
               "'\r\n客戶端Identity是 '" + ClientIdentity + "'";
    }
}

所有範例採自宿主 Console 應用程式,搭配 TcpTrace 監聽 8055 埠、實際服務跑 8056 埠,以觀察封包內容。

安全模式:None(無安全性)

設定 SecurityMode.None 後,訊息以明文 Text/XML 傳輸,無完整性、機密性、驗證保護。適用於純測試或受信任區域網路。

關鍵程式碼片段

// 服務端
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.None;
Uri baseAddress = new Uri("https://localhost:8056/WCFService/");
ServiceHost host = new ServiceHost(typeof(GetIdentity), baseAddress);
host.AddServiceEndpoint(typeof(IGetIdentity), binding, "GetIdentity");
// 啟用 MEX
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri("https://localhost:8057/mex");
host.Description.Behaviors.Add(behavior);
host.Open();

// 客戶端
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.None;
EndpointAddress ea = new EndpointAddress("https://localhost:8056/WCFService/GetIdentity");
GetIdentityClient client = new GetIdentityClient(binding, ea);
// 設定 Via 行為供 TcpTrace 監聽
client.Endpoint.Behaviors.Add(new ClientViaBehavior(new Uri("https://localhost:8055/WCFService/GetIdentity")));
string result = client.Get(WindowsIdentity.GetCurrent().Name);

None 模式客戶端執行結果

TcpTrace 擷取封包顯示 SOAP Body 明文可讀,確認無加密。

安全模式:Transport(HTTPS 傳輸層安全)

Transport 模式透過 HTTPS 保障訊息機密性與完整性。服務端必須擁有 SSL 憑證並綁定至特定埠口;自宿主需用 netsh http add sslcert(Vista/Server 2008)或 httpcfg(XP/Server 2003)指令綁定。Endpoint 位址必須使用 https:// 結構描述。

2.1 客戶端驗證:None

僅伺服器憑證驗證伺服器身分,客戶端匿名。

2.2 客戶端驗證:Basic

客戶端提供使用者名稱/密碼(Base64 編碼),透過 SSL 加密傳輸。程式碼設定 HttpClientCredentialType.Basic 並在客戶端指定 ClientCredentials.UserName。

2.3 客戶端驗證:Ntlm

使用 Windows 整合驗證(NTLM 挑戰/回應機制),密碼不傳輸明文。適用於同網域或同帳號密碼的工作群組環境。

2.4 客戶端驗證:Windows

與 Ntlm 類似,但支援 Kerberos 協商:雙方同屬網域且以網域帳號登入時自動升級為 Kerberos,否則回退 NTLM。

2.5 客戶端驗證:Certificate

雙向憑證驗證:服務端憑證建立 SSL,客戶端憑證識別呼叫者。需分別產生伺服器(CN=win2008)與客戶端(CN=TestClient)憑證,並匯入對方信任的根憑證授權單位存儲區。

關鍵指令:產生與綁定憑證

// 產生伺服器憑證
makecert -sr localmachine -ss My -n CN=win2008 -sky exchange -pe -r

// 產生客戶端憑證
makecert -sr currentuser -ss My -n CN=TestClient -sky exchange -pe -r

// Vista/Server 2008 綁定憑證至埠 8056
netsh http add sslcert ipport=0.0.0.0:8056 certhash=THUMBPRINT appid={GUID} clientcertnegotiation=enable

憑證指紋檢視

Transport None 測試結果

Transport Basic 測試結果

Transport NTLM 測試結果

Transport Certificate 測試結果

嚴重問題:機器重啟後 SSL 埠口綁定失效

所有 Transport 模式測試在重啟前正常,重啟後客戶端拋出「無法建立 SSL/TLS 安全通道」異常,但 netsh http show sslcert 顯示綁定仍存在。必須刪除再重新綁定才能恢復。根因未明,疑為 HTTP.sys 驅動程式載入順序或憑證存儲區存取時機問題。若有解決方案請不吝分享。

重啟後異常畫面

重啟後 netsh 查詢結果

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved