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

WCF 安全實戰:使用者名稱/密碼驗證搭配 X.509 憑證加密傳輸

     編輯:關於.NET

WCF 安全機制提供訊息層與傳輸層防護。本文示範 wsHttpBinding 結合 使用者名稱/密碼驗證(訊息層)與 X.509 憑證加密(保護認證資訊)的完整實作。

憑證準備

使用 makecert 建立自我簽署憑證並匯入信任清單:

makecert -sr LocalMachine -ss My -a sha1 -n CN=Webabcd -sky exchange -pe
certmgr -add -r LocalMachine -s My -c -n Webabcd -s TrustedPeople

服務端實作

自訂驗證器

public class CustomNamePasswordValidator : UserNamePasswordValidator {
    public override void Validate(string userName, string password) {
        if (!(userName == "webabcd" && password == "webabcd")) {
            throw new FaultException("使用者名稱或密碼不正確");
        }
    }
}

服務契約與實作

[ServiceContract]
public interface IHello {
    [OperationContract] string SayHello(string name);
}

public class Hello : IHello {
    public string SayHello(string name) => "Hello: " + name;
}

Web.config 關鍵設定

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="SecurityBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceCredentials>
          <!-- 使用者名稱/密碼驗證模式:Custom 使用自訂驗證器 -->
          <userNameAuthentication 
              userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="WCF.ServiceLib.Security.CustomNamePasswordValidator, WCF.ServiceLib" />
          <!-- 服務憑證:用於加密 SOAP Header 中的認證資訊 -->
          <serviceCertificate 
              findValue="Webabcd" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>

  <bindings>
    <wsHttpBinding>
      <binding name="SecurityBindingConfiguration">
        <security>
          <message clientCredentialType="UserName" /> <!-- 訊息層認證 -->
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>

  <services>
    <service name="WCF.ServiceLib.Security.Hello" behaviorConfiguration="SecurityBehavior">
      <endpoint address="" binding="wsHttpBinding" contract="WCF.ServiceLib.Security.IHello" bindingConfiguration="SecurityBindingConfiguration" />
    </service>
  </services>
</system.serviceModel>

客戶端實作

Web.config 端點身分識別與驗證設定

<client>
  <endpoint address="https://localhost:3502/ServiceHost/Security/Hello.svc"
      binding="wsHttpBinding" contract="SecuritySvc.IHello"
      bindingConfiguration="HelloBindingConfiguration"
      behaviorConfiguration="HelloBehaviorConfiguration">
    <identity>
      <!-- 服務公開金鑰,用於加密使用者名稱/密碼 -->
      <certificate encodedValue="AwAAAAEAAAAUAAAAwMJESjc9Bbgeh9hIrrdrlMz0nfEgAAAAAQAAALMBAAAwggGvMIIBXaADAgECAhBC+dqPonX5pEwDPMLbdE9MMAkGBSsOAwIdBQAwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3kwHhcNMDgwNzE1MDczODIwWhcNMzkxMjMxMjM1OTU5WjASMRAwDgYDVQQDEwdXZWJhYmNkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwfrBPcMSOWVJmDnn+EFfCOslH0OqC5s67C6e19XQ7oMh6a9hP9Os4hefNoGxcdPK3orV4y4pHn0VOvHgaeAJqreRjmgmyb+h2BDB7nkmhchBxQZUx4jSX0GUrqECZm9uUMrNq8vx7NtaEuEMs5q50KPaxrv6PwuKLssNnb3WC1wIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwCQYFKw4DAh0FAANBAE/6rAQhU3X1RficEHPEeUAX7HQQXZDYByQt0QqE7C8PaViQWlWU+Sp8u9Oy3ce4DSg3wgQLL/DIknG7FMIiGRE=" />
    </identity>
  </endpoint>
</client>

<behaviors>
  <endpointBehaviors>
    <behavior name="HelloBehaviorConfiguration">
      <clientCredentials>
        <serviceCertificate>
          <!-- PeerTrust:憑證在 TrustedPeople 存儲區即信任 -->
          <authentication certificateValidationMode="PeerTrust" />
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

<bindings>
  <wsHttpBinding>
    <binding name="HelloBindingConfiguration">
      <security>
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

呼叫程式碼

using (var proxy = new SecuritySvc.HelloClient()) {
    proxy.ClientCredentials.UserName.UserName = "webabcd";
    proxy.ClientCredentials.UserName.Password = "webabcd";
    string result = proxy.SayHello("webabcd"); // 回傳 "Hello: webabcd"
}

運作流程說明

  1. 客戶端取得服務公開金鑰(透過 <identity> 設定)
  2. 呼叫時將使用者名稱/密碼以公開金鑰加密,放入 SOAP Header
  3. 服務端以私鑰解密,交由 CustomNamePasswordValidator 驗證
  4. 驗證通過執行業務邏輯,回傳結果

憑證驗證模式選擇

模式說明
None不驗證憑證
PeerTrust憑證位於 TrustedPeople 存儲區即信任(測試常用)
ChainTrust憑證鏈結至受信任根憑證授權單位
PeerOrChainTrust上述兩者任一符合即信任
Custom自訂 X509CertificateValidator

此架構確保認證資訊在網路傳輸中經過加密,防止竊聽與中間人攻擊,是企業級 WCF 安全的經典實作模式。

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