Nginx集群之WCF分散式身份驗證(支持Soap)

来源:http://www.cnblogs.com/yongfeng/archive/2017/11/20/7867775.html
-Advertisement-
Play Games

Nginx是個輕量級的反向代理,當然,也有相應的SSL身份認證。本文主要採用一種自我寄宿的方式,使用Nginx集群,通過windows證書(X.509證書),講述客戶端如何訪問伺服器的方法。客戶端以BasicHttpBinding進行訪問Nginx,然後Nginx進行負載均衡,將消息分發到後端任意一... ...


目錄

1       大概思路... 1

2       Nginx集群之WCF分散式身份驗證... 1

3       BasicHttpBinding、ws2007HttpBinding. 2

4       Windows證書生成私鑰、公鑰(X.509證書)... 3

5       編寫WCF服務、客戶端程式... 7

6       URL保留項... 13

7       部署WCF服務程式到區域網內3台PC機... 14

8       Nginx集群配置搭建... 15

9       SoapUI和WCF客戶端程式的運行結果... 16

10     總結... 18

1       大概思路

l  Nginx集群之WCF分散式身份驗證

l  BasicHttpBinding、Ws2007HttpBinding

l  Windows證書生成公鑰、私鑰(x509證書)

l  編寫WCF服務、客戶端程式

l  URL保留項

l  部署WCF服務程式到區域網內3台PC機

l  Nginx集群配置搭建

l  SoapUI和WCF客戶端程式的運行結果

l  總結

2       Nginx集群之WCF分散式身份驗證

Nginx是個輕量級的反向代理,當然,也有相應的SSL身份認證。本文主要採用一種自我寄宿的方式,使用Nginx集群,通過windows證書(X.509證書),講述客戶端如何訪問伺服器的方法。

 

本文源代碼主要分類:

l  HighlyConcurrentHosting

使用BasicHttpBinding的源代碼(本文主要以這種方式進行Nginx集群)

l  HighlyConcurrentHosting_Ws2007HttpBinding

使用ws2007HttpBinding的源代碼(這是一種點對點的Windows認證方式)

l  Nginx配置

nginx.conf

l  Windows證書

wcf_zhyongfeng.cer(客戶端需要安裝的證書)

wcf_zhyongfeng.pfx(伺服器需要安裝的證書)

 

以下是本文講述的主要結構圖:

客戶端以BasicHttpBinding進行訪問Nginx,然後Nginx進行負載均衡,將消息分發到後端任意一臺WCF的PC機,後端需要被訪問的WCF伺服器,都要安裝Windows證書(僅被訪問的伺服器需要安裝wcf_zhyongfegn.pfx證書)。

 

若以ws2007HttpBinding進行點對點Windows認證,則Nginx只能起到通過劃分IP綁定特定一臺伺服器訪問的作用,並不能起到集群負載均衡,同時除了伺服器要wcf_zhyongfeng.pfx安裝證書外,客戶端也需要進行安裝wcf_zhyongfeng.cer證書,這裡不作為重點講述。

3       BasicHttpBinding、ws2007HttpBinding

這裡WCF的Ningx集群,主要用的是BasicHttpBinding。BasicHttpBinding的預設安全模式是None,即沒有任何安全設置,消息都以明文傳送,對客戶端也不進行驗證。  但是basicHttpBinding綁定可以實現安全傳輸,也可以通過傳輸層和消息層來保證消息的安全性。  basicHttpBinding設置為Transport安全模式,傳輸層的安全是使用IIS的安全機制,比如基本身份驗證、集成windows驗證、SSL安全通道等等

.NET Framework 3.5 介紹了一種用於Web 服務交互稱為ws2007HttpBinding綁定的新的綁定。這個綁定類似於ws2007HttpBinding綁定除了它支持最新的WS-* 消息,安全,可信賴消息和事務標準。

ws2007HttpBinding支持的標準:

WS-SecureConversation v1.3

WS-Security的擴展,為多個消息交換提供一個安全上下文

WS-Trust v1.3

WS-Security的擴展,請求並標記問題,管理可依賴關係。

WS-SecurityPolicy v1.2

WS-Security的安全斷言,WS-Security轉換以及使用WS-Policy表達的WS-Trust

Web Services Reliable Messaging v1.1

保證消息被傳遞,適當編碼且不會重覆接收的協議

Web Services Coordination v1.1

為分散式平臺的動作合作提供協議的平臺

 

4       Windows證書生成私鑰、公鑰(X.509證書)

進行C:\Windows\system32,以管理員運行cmd.ext

Microsoft Windows [版本 6.1.7601]
版權所有 (c) 2009 Microsoft Corporation。保留所有權利。

C:\Windows\system32>cd C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin

C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin>makecert -r -pe -n "CN=wcf_zhyongfeng" -ss My -sky exchange
Succeeded

C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin>

查看Windows證書的生成,開始->運行,輸入:

certmgr.msc

Windows導出wcf_zhyongfeng.pfx服務端證書:

Windows導出wcf_zhyongfeng.cer客戶端證書:

5       編寫WCF服務、客戶端程式

l  WCF服務程式

Program.cs

using Service;
using System;
using System.ServiceModel;

namespace HighlyConcurrentHosting
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(OutputSomething)))
            {
                host.Opened += delegate
                {
                    Console.WriteLine(host.Description.Endpoints[0].Address.Uri + "已經啟動,按任意鍵終止服務!");
                };

                host.Open();
                Console.Read();
            }
        }
    }

    /// <summary>
    /// 證書驗證帳戶名,密碼
    /// </summary>
    public class UserNamePasswordValidator : System.IdentityModel.Selectors.UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (userName != "zhyongfeng" || password != "123456")
            {
                throw new System.IdentityModel.Tokens.SecurityTokenException("Unknown Username or Password");
            }
        }
    }
}

服務端配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="metadataBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <!-- 要接收故障異常詳細信息以進行調試,請將以下值設置為 true。在部署前設置為 false 以避免泄漏異常信息 -->
          <serviceDebug includeExceptionDetailInFaults="true"/>

          <serviceCredentials>
            <!--指定一個 X.509 證書,用戶對認證中的用戶名密碼加密解密-->
            <!--C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin,使用makecert -r -pe -n "CN=wcf_zhyongfeng" -ss My -sky exchange-->
            <serviceCertificate findValue="wcf_zhyongfeng" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My"/>
            <clientCertificate>
              <!--自定義對客戶端進行證書認證方式 這裡為 None-->
              <authentication certificateValidationMode="None"></authentication>
            </clientCertificate>

            <!--自定義用戶名和密碼驗證的設置-->
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="HighlyConcurrentHosting.UserNamePasswordValidator,HighlyConcurrentHosting" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <bindings>
      <basicHttpBinding>
        <!--這個是需要輸入用戶名密碼的-->
        <binding name="YesCertificate">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic"></transport>
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </basicHttpBinding>
  </bindings>

    <services>
      <service name="Service.OutputSomething" behaviorConfiguration="metadataBehavior" >
        <host>
          <baseAddresses>
            <add baseAddress="http://127.0.0.1:5600/hello"/>
          </baseAddresses>
        </host>
        <endpoint binding="basicHttpBinding" bindingConfiguration="YesCertificate" contract="Service.Interface.IOutputSomething"/>
        <endpoint binding="basicHttpBinding" bindingConfiguration="YesCertificate" contract="Service.Interface.IOutputSomethingCertificate" />
      </service>
    </services>
  </system.serviceModel>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

 

l  客戶端程式

using HighlyConcurrentClient.HighlyConcurrentService;
using System;
using System.Net;

namespace HighlyConcurrentClient
{
    class Program
    {
        static void Main(string[] args)
        {

            string AddressIP = string.Empty;
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                {
                    AddressIP = _IPAddress.ToString();
                }
            }
            Console.WriteLine(string.Format("本機IP是:{0}", AddressIP));
            using (OutputSomethingCertificateClient proxy = new OutputSomethingCertificateClient())
            {
                
                proxy.ClientCredentials.UserName.UserName = "zhyongfeng";
                proxy.ClientCredentials.UserName.Password = "123456";
                for (int i = 0; i < 20; i++)
                {
                    Console.WriteLine(proxy.GetCertContentData(i));
                }
            }
            Console.Read();
        }
    }
}

客戶端配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IOutputSomething">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic" />
          </security>
        </binding>
        <binding name="BasicHttpBinding_IOutputSomethingCertificate">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://zhyongfeng.com/hello" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IOutputSomething" contract="HighlyConcurrentService.IOutputSomething"
        name="BasicHttpBinding_IOutputSomething" />
      <endpoint address="http://zhyongfeng.com/hello" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IOutputSomethingCertificate"
        contract="HighlyConcurrentService.IOutputSomethingCertificate"
        name="BasicHttpBinding_IOutputSomethingCertificate" />
    </client>
  </system.serviceModel>
</configuration>

客戶端添加引用時,會產生

客戶端添加服務引用後,Address可能是某一臺PC機的IP地址(例如:address="http:// 10.92.202.56:5600/hello")這是需要修改為以下Nginx的地址

address="http://zhyongfeng.com/hello".

即如圖所示:

6       URL保留項

詳見:http://www.cnblogs.com/yongfeng/p/7851039.html

7       部署WCF服務程式到區域網內3台PC機

遠程進行部署WCF服務程式時,需要雙擊安裝伺服器wcf_zhyongfeng.pfx證書、修改config三台機的配置文件:10.92.202.56:5600、10.92.202.57:5700、10.92.202.58:5800

然後啟動遠程電腦的WCF服務程式,運行效果如下:

本機IE上訪問WCF服務端的運行效果:

8       Nginx集群配置搭建

通過自主義功能變數名稱zhyongfeng.com:80埠進行負載均衡集群訪問,則訪問C:\Windows\System32\drivers\etc\hosts,添加下列“本機IP 自定義的功能變數名稱”:

10.93.85.66    zhyongfeng.com

針對WCF部署的多台PC機配置(設置了proxy_connect_timeout為10s,如果其中一臺機down掉了,可以轉發到另一臺機器)如下:

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    upstream zhyongfeng.com {
        server    10.92.202.56:5600;
        server    10.92.202.57:5700; 
        server    10.92.202.58:5800;
    }
    server {
        listen       80;
        server_name  zhyongfeng.com;
        location / {
            proxy_pass   http://zhyongfeng.com;
            proxy_connect_timeout       10s;
        } 
    }
}

運行CMD:

D:\DTLDownLoads\nginx-1.10.2>start nginx

D:\DTLDownLoads\nginx-1.10.2>nginx -s reload

訪問WCF服務端:http://zhyongfeng.com/hello,運行結果:

9       SoapUI和WCF客戶端程式的運行結果

Soap協議,可以使用SoapUI測試並添加WCF的wsdl:http://zhyongfeng.com/hello?wsdl,運行效果如下:

啟動WCF客戶端程式,運行效果圖如下:

遠程桌面關掉其中一臺10.92.202.56:5600的PC機:

重新啟動WCF客戶端程式,因為Nginx配置文件設置了proxy_connect_timeout為10s,則關閉的PC機10.92.202.56:5600在10s後會將它的消息轉發給10.92.202.57:5700,繼續由其它2台PC機執行:

10             總結

通過使用BasicHttpBinding,除了能讓WCF客戶端訪問之外,還增加了WSDL的訪問方式。Nginx集群讓WCF客戶端具備用戶名密碼驗證的同時,達到負載均衡分散式處理的效果。

 

源代碼下載:

http://download.csdn.net/download/ruby_matlab/10126187

 

PDF下載:

Nginx集群之WCF分散式身份驗證(支持soap).pdf


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 操作系統的內核(Kernel) 是一組程式,這組程式的重點在於管理電腦的所有活動以及驅動系統中的所有硬體。 有了內核後,開發者不必自己去考慮機器語言、所有硬體的相關參數、程式的可移植性、專一性了。但是由於開發者使用的是操作系統提供的介面,所以需要考慮應用將在哪個操作系統中運行。 內核的功能有: 操 ...
  • 3.1 電磁干擾 EMI第一個知識點, 去耦電容的應用。 那首先要介紹一下去耦電容的應用背景, 這個背景就是電磁干擾, 也就是“傳說中” 的 EMI。1、 冬天的時候, 尤其是空氣比較乾燥的內陸城市, 很多朋友都有這樣的經歷, 手觸碰到電腦外殼、 鐵柜子等物品的時候會被電擊, 這就是“靜電放電” 現 ...
  • 預設tree命令是無法使用的,可以使用homebrew install tree安裝。 如果直接使用tree,查看的目錄裡面含有中文字元的目錄或文件時會出現漢字不能顯示的問題,可以使用tree -N查看。 ...
  • 本地YUM源伺服器最大優點是區域網的快速網路連接和穩定性。有了區域網中的YUM源伺服器,即便在Internet連接中斷的情況下,也不會影響其他YUM客戶端的軟體安裝和升級。 ...
  • 經過前面幾章的姍姍學步,我們瞭解了在 ASP.NET Core 中是如何認證的,終於來到了授權階段。在認證階段我們通過用戶令牌獲取到用戶的Claims,而授權便是對這些的Claims的驗證,如:是否擁有Admin的角色,姓名是否叫XXX等等。本章就來介紹一下 ASP.NET Core 的授權系統的簡 ...
  • 背水一戰 Windows 10 之 控制項(控制項基類 - UIElement ): 與 CanDrag 相關的事件(DragStartingEventArgs, DropCompletedEventArgs), 與 AllowDrop 相關的事件(DragEventArgs) ...
  • 返回總目錄 本小節目錄 Replace Method with Method Object(以函數對象取代函數) Substitute Algorithm(替換演算法) 階段性小結 Substitute Algorithm(替換演算法) 8 Replace Method with Method Obje ...
  • 回到目錄 在進行.net core平臺之後,我們如果希望在請求過程中添加一些事件是非常容易的,你可以把這些事件做成一個中間件Middleware,然後這些中間件就會以Http pipeline的管道方式進行相應,並且它們就像是一個職責鏈,從你定義的第一個中間件開始,一個一個向下傳遞,直到最後一個中間 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...