WCF帳戶密碼認證

記錄一下我實現WCF用戶認證與權限控制的實現方法, 也讓其餘網友少走一些彎路. 內容寫得很是小白(由於我也是小白嘛), 比較詳細, 方便WCF知識基礎薄的朋友html

主要分爲下面幾個步驟 數據庫

  1. 做爲例子, 建立最簡單的WCF服務
  2. 生成X.509證書, 並導入到服務端和客戶端
  3. 爲服務提供賬號密碼驗證程序, 並配置App.config
  4. 生成客戶端並配置其App.config

這裏要解釋一下爲何要用X509證書: 由於咱們須要X509證書這種非對稱密鑰技術來實現WCF在Message傳遞過程當中的加密和解密,要否則用戶名和密碼就得在網絡上明文傳遞!詳細說明就是客戶端把用戶名和密碼用公鑰加密後傳遞給服務器端,服務器端再用本身的私鑰來解密,而後傳遞給相應的驗證程序來實現身份驗證安全

 

0. 開發環境bash

Win7 64bit服務器

VS2010 或者更高網絡

.Net Framework 4ide

 

1. 新建服務端測試

建立一個最基本的WCF服務, 我這裏命名爲 WCF_UserPassword, 接下來咱們將直接使用裏面的GetData方法ui

image

直接按F5, 你就可使用WCF測試服務端, 看到服務已經可使用了加密

image

 

2. 生成X.509證書, 並導入到服務端和客戶端

生成X509證書須要用到makecert.exe, 只要安裝了Visual Studio, 就能夠在C盤找到, 爲了操做方便, 將它拷貝到 D:\Cert\; 安裝證書須要用到CertMgr.exe, 因此也拷貝進來吧, 這兩個exe都有32位版本和64位版本, 請拷貝與本身系統一致的版本; 最後還要用到pvk2pfx.exe, 這個只有32位版本(VS2013 又有64位版本)

2.1. 服務端和客戶端 在同一臺電腦上的狀況

在服務端生成X.509證書

打開CMD, 切換到D:\Cert\, 運行下面這個命令

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

這個命令的意思就是建立一個測試的X509證書,這個證書放在存儲位置爲"Localmachine"(本地計算機)的"My"(我的)這個證書文件夾下,證書主題名字叫"MyServerCert"

你能夠經過mmc查看是否安裝成功, 運行mmc --> 文件-->添加/刪除管理單元-->可用的管理單元 下面選擇 證書 -->選擇計算機帳戶 --> 選擇本地計算機--> 完成

image

2.2. 將服務器證書公匙安裝到客戶端的 受信任人的存儲區中

certmgr.exe -add -r LocalMachine -s My -c -n MyServerCert -r LocalMachine -s TrustedPeople

由於客戶端系統不隱式信任 Makecert.exe 生成的證書,因此須要執行此步驟。若是您已經擁有一個證書,該證書來源於客戶端的受信任根證書(例如由 Microsoft 頒發的證書),則不須要執行使用服務器證書填充客戶端證書存儲區這一步驟。

2.3. 服務端和客戶端 在不一樣電腦上 的狀況(這個例子裏沒有用到這節內容)

生成密匙

makecert -r -pe -sky exchange -n "CN=MyServerCert" MyServerCertPublicKey.cer -sv MyServerCertPrivateKey.pvk
pvk2pfx.exe -pvk MyServerCertPrivateKey.pvk -spc MyServerCertPublicKey.cer -pfx MyServerCertExchange.pfx

你將獲得

MyServerCertExchange.pfx     //密匙交換文件
MyServerCertPrivateKey.pvk    //私匙
MyServerCertPublicKey.cer     //公匙

 

在服務端: 將MyServerCertExchange.pfx導入到 本地計算機證書 -->我的--> 證書

CMD: certmgr.exe -add -c MyServerCertExchange.pfx -r LocalMachine -s my

在客戶端: 將MyServerCertPublicKey.cer 導入到 本地計算機證書 --> 受信任人-->證書

CMD: certmgr.exe -add -c MyServerCertPublicKey.cer -r LocalMachine -s TrustedPeople

3. 添加驗證程序

添加一個 繼承自System.IdentityModel.Selectors.UserNamePasswordValidator 的MyCustomValidator 類, 重寫裏面的Validate方法來實現用戶名密碼認證邏輯

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

namespace WCF_UserPassword
{
    public class MyCustomValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            //這裏僅簡單演示一下, 實際工做中應該是使用 數據庫查詢 
            if (userName == "admin" && password == "admin") return;
            if (userName == "admin2" && password == "admin2") return;
            
            throw new FaultException("用戶名或者密碼錯誤!");
            //throw new SecurityTokenException("用戶名或者密碼錯誤!"); //這種異常, 客戶端將不能獲得 錯誤信息
        }
    }
}

這須要添加引用 System.IdentityModel.dll

image

 

4. 配置服務端App.config, 主要包括如下內容

  1. 將basicHttpBinding 修改成wsHttpBinding
  2. 建立一個新wsHttpBinding的配置
  3. 服務行爲中添加一個serviceCredentials

4.1. 將basicHttpBinding 修改成wsHttpBinding

image

4.2. 建立一個新wsHttpBinding的配置, 命名爲wsHttpBindingToUserPassword

image

這個的設置改動只有一個, 切換至 安全性Tab, 把MessageClientCredentialType 從 Windows 改成 UserName

image

在配置文件App.config 中顯示的是

<binding name="wsHttpBindingToUserPassword">
  <security>
    <message clientCredentialType="UserName" />
  </security>
</binding>

4.3. 服務行爲中添加一個serviceCredentials(最核心的設置)

高級-->服務行爲-->右鍵 空名稱, 選擇: 添加服務行爲元素擴展

image

添加serviceCredentials

image

命名爲 ServiceBehaviorToUserPassword

image

雙擊serviceCredentials進入編輯

image

將userNamePasswordValidationMode 改成 Custom, 將customUserNamePasswordValidatorType填入"WCF_UserPassword.MyCustomValidator,WCF_UserPassword"

image

展開serviceCredentials就能夠看到serviceCertificate, 將FindValue填入MyServerCert, 將X509FindType從FindBySubjectDistinguishedName改成FindBySubjectName

image

默認狀況下, 客戶端須要使用信任鏈對證書進行驗證, 但因爲導入到客戶端的證書是咱們本身建立的, 不具備可驗證的信任鏈, 因此須要繼續修改clientCertificate, CertificateValidationMode改成PeerTrust(只有證書在TrustedPeople 就徹底信任), 將FindValue填入MyServerCert, StoreLocation改成LocalMachine, StoreName改成TrustedPeople, 將X509FindType從FindBySubjectDistinguishedName改成FindBySubjectName

image

4.4. 將以上添加的節點配置到服務中去

ServiceBehaviorToUserPassword 配置到 服務的behaviorConfiguration

image

將wsHttpBindingToUserPassword配置到終結點的bindingConfiguration

image

4.5. 將終結點的Dns從默認的localhost改成MyServerCert

image

5. 如今你能夠運行服務端了, 調用GetData方法將彈出 "指定用戶名" 的錯誤, 這表示咱們服務端的配置起效了

image

6. 從新打開一個Visual Studio, 新建一個Console控制檯程序, 命名爲WCF_Client

運行服務端, 以方便客戶端獲取服務信息, 服務地址通常都很長, 仍是直接複製服務地址吧

image

控制檯程序的引用上添加服務引用

image

就直接使用默認的命名ServiceReference1吧

image

讓咱們看看客戶端代碼

static void Main(string[] args)
{
    var proxy = new ServiceReference1.Service1Client();
    proxy.ClientCredentials.UserName.UserName = "admin";
    proxy.ClientCredentials.UserName.Password = "admin";
 
    try
    {
        Console.WriteLine(proxy.GetData(2));
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

 

運行結果

image

 

源代碼 WCF_Course帳戶密碼認證.rar, 運行程序, 至少須要你完整完成第二步 "生成X.509證書, 並導入到服務端和客戶端"

相關文章
相關標籤/搜索