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

WCF 使用者名稱密碼驗證完整實作指南

     編輯:關於.NET

在早期使用 Web Service 建構分散式系統時,身分驗證一直是個棘手的問題。傳統做法需繼承 SoapHeader,將帳號密碼放入其中,每次呼叫方法都得傳遞認證資訊給伺服器驗證,不僅效率低落、程式碼繁瑣,更存在明文傳輸的安全隱憂。

WCF 多元驗證機制與用戶名密碼認證原理

WCF 內建支援 Windows 驗證、X.509 憑證、Issued Tokens 及用戶名密碼等多種驗證技術。在跨 Windows 網域的分散式系統中,用戶名密碼認證仍是最常採用的方式。然而,實作此機制必須搭配 X.509 憑證,原因在於需要非對稱加密技術保護訊息傳遞過程中的用戶名密碼,避免在網路上明文傳輸。運作流程為:客戶端使用公開金鑰加密認證資訊傳送,伺服器端以私鑰解密後交由驗證邏輯處理。

建立測試用 X.509 憑證

開發測試階段無需申請正式數位憑證,微軟提供 makecert.exe 工具產生測試憑證。在命令提示字元執行:

makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=MyServerCert -sky exchange –pe

此命令會在「LocalMachine」存儲區的「My」資料夾建立主體名稱為「MyServerCert」的測試憑證。更多參數說明請參考 MSDN 文件。

伺服器端實作:自訂驗證邏輯與組態設定

1. 建立自訂驗證器

在 WCF 專案加入 System.IdentityModel 參考,新增類別繼承 UserNamePasswordValidator 並覆寫 Validate 方法:

using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

namespace ServerWcfService.CustomValidators
{
    public class MyCustomValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (string.IsNullOrEmpty(userName))
                throw new ArgumentNullException("userName");
            if (string.IsNullOrEmpty(password))
                throw new ArgumentNullException("password");

            // 實際應用中應從資料庫驗證
            if (userName != "xiaozhuang" || password != "123456")
                throw new SecurityTokenException("用戶名或者密碼錯誤!");
        }
    }
}

驗證失敗時拋出 SecurityTokenException,實際專案中帳密通常存放於資料庫。

2. 設定 Web.config

重點在於 <system.serviceModel> 區段設定:

  • Bindings:指定 wsHttpBinding 的安全模式為 Message,客戶端認證類型為 UserName
  • Endpoint:設定 <identity><dns value="MyServerCert"/></identity>,值需與憑證 CN 名稱一致
  • ServiceCredentials:
    • <serviceCertificate>:指定憑證位置(LocalMachine/My/FindBySubjectName/MyServerCert),用於訊息加解密
    • <userNameAuthentication>:設定 userNamePasswordValidationMode="Custom" 並指定自訂驗證器型別

客戶端實作與測試憑證信任問題解決

1. 基本呼叫程式碼

protected void btnPrint_Click(object sender, EventArgs e)
{
    TestWCFService.MySimpleServiceClient client = new ClientWeb.TestWCFService.MySimpleServiceClient();
    client.ClientCredentials.UserName.UserName = "xiaozhuang";
    client.ClientCredentials.UserName.Password = "123456";
    lbMessage.Text = client.PrintMessage(txtMessage.Text);
}

2. 繞過測試憑證信任鏈驗證

測試憑證非受信任根憑證機構簽發,直接執行會拋出「X.509 certificate CN=MyServerCert 鏈生成失敗」錯誤。解決方法是實作自訂 X509CertificateValidator:

using System.Configuration;
using System.IdentityModel.Selectors;
using System.Security.Cryptography.X509Certificates;

namespace ClientWeb.CustomX509Validator
{
    public class MyX509Validator : X509CertificateValidator
    {
        public override void Validate(X509Certificate2 certificate)
        {
            if (certificate == null)
                throw new ArgumentNullException("X509認證證書為空!");

            // 僅驗證主體名稱,實際專案應加強驗證邏輯
            if (certificate.SubjectName.Name != ConfigurationManager.AppSettings["CertName"])
                throw new SecurityTokenValidationException("Certificated was not issued by thrusted issuer");
        }
    }
}

在客戶端 Web.config 加入 <endpointBehaviors>,設定 certificateValidationMode="Custom" 並指定自訂驗證器型別,於 <endpoint> 套用 behaviorConfiguration="myClientBehavior" 即可正常執行。

執行結果畫面

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