Nginx集群可以實現基於Http Basic身份驗證,通過輸入用戶、密碼,經過SSL協議的HTTPS,從而實現有效的身份驗證並訪問相應的WebApi。當然,訪問的方式不僅僅基於Http Basic一種,還可以通過令牌token的方式進行訪問,又或者基於redis實現單點登錄的訪問,本文主要講述的是... ...
目錄
1 大概思路... 1
2 Nginx集群之SSL證書的WebApi身份驗證... 1
3 AuthorizeAttribute類... 2
4 Openssl生成SSL證書... 2
5 編寫.NET WebApi 2
6 部署WebApi到區域網內3台PC機... 5
7 Nginx集群配置搭建... 6
8 運行結果... 7
9 總結... 9
1 大概思路
l Nginx集群之SSL證書的WebApi身份驗證
l AuthorizeAttribute類
l Openssl生成SSL證書
l 編寫.NET WebApi
l 部署WebApi到區域網內3台PC機
l Nginx集群配置搭建
l 運行結果
l 總結
2 Nginx集群之SSL證書的WebApi身份驗證
Nginx集群可以實現基於Http Basic身份驗證,通過輸入用戶、密碼,經過SSL協議的HTTPS,從而實現有效的身份驗證並訪問相應的WebApi。當然,訪問的方式不僅僅基於Http Basic一種,還可以通過令牌token的方式進行訪問,又或者基於redis實現單點登錄的訪問,本文主要講述的是基於Http Basic身份驗證,併在HTTPS安全的通信下,實現簡單集群身份驗證。
以下是本文講述的主要結構圖:
客戶端輸入用戶名密碼,訪問Nginx的URL:https://zhyongfeng.com/api/user/GetMachine,然後Nginx進行負載均衡,返回https的響應。Nginx集群之SSL證書的WebApi身份驗證架構,如下圖所示:
BASIC認證的缺點
HTTP基本認證的目標是提供簡單的用戶驗證功能,其認證過程簡單明瞭,適合於對安全性要求不高的系統或設備中,如大家所用路由器的配置頁面的認證,幾乎都採取了這種方式。其缺點是沒有靈活可靠的認證策略,如無法提供域(domain或realm)認證功能,另外,BASE64的加密強度非常低。當然,HTTP基本認證系統也可以與SSL或者Kerberos結合,實現安全性能較高(相對)的認證系統。
3 AuthorizeAttribute類
當你使用 AuthorizeAttribute 標記某個操作方法時,對該操作方法的訪問將限於已經過身份驗證且獲得授權的用戶。
如果使用該特性標記某個控制器,則該控制器中的所有操作方法均將受到限制。
Authorize 特性允許你指示將授許可權於預定義角色或個別用戶。 這使你可以對誰有權查看站點上的任何頁面進行嚴格控制。
如果未經授權的用戶嘗試訪問使用 Authorize 特性標記的方法,MVC 框架將返回 401 HTTP 狀態代碼。
如果站點配置為使用 ASP.NET 窗體身份驗證,則 401 狀態代碼會導致瀏覽器將用戶重定向到登錄頁。
從AuthorizeAttribute派生,如果要從 AuthorizeAttribute 類派生,則派生的類型必須是線程安全的。
因此,不要在類型實例本身中(例如,在實例欄位中)存儲狀態(除非該狀態要應用於所有請求), 而應在 Items 屬性中按請求存儲狀態,該屬性可通過傳遞給 AuthorizeAttribute 的上下文對象進行訪問。
具體特性可以訪問:
https://msdn.microsoft.com/zh-cn/library/system.web.mvc.authorizeattribute.aspx
4 Openssl生成SSL證書
請參照《Nginx集群之SSL證書的WebApi微服務》
http://www.cnblogs.com/yongfeng/p/7921905.html
5 編寫.NET WebApi
伺服器端:
CustomAuthorizeAttribute.cs
using System.Web.Http; using System.Web.Http.Controllers; namespace SSLWebApi.Controllers { public class CustomAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(HttpActionContext actionContext) { //判斷用戶是否登錄 if (actionContext.Request.Headers.Authorization != null) { string userInfo = System.Text.Encoding.Default.GetString(System.Convert.FromBase64String(actionContext.Request.Headers.Authorization.Parameter)); //用戶驗證邏輯 if (string.Equals(userInfo, string.Format("{0}:{1}", "zhyongfeng", "123456"))) { IsAuthorized(actionContext); } else { HandleUnauthorizedRequest(actionContext); } } else { HandleUnauthorizedRequest(actionContext); } } protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext) { var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized); challengeMessage.Headers.Add("WWW-Authenticate", "Basic"); throw new System.Web.Http.HttpResponseException(challengeMessage); } } }
BaseController.cs
using System.Web.Http; namespace SSLWebApi.Controllers { /// <summary> /// BaseController繼承BaseController則需要身份驗證 /// </summary> [CustomAuthorize] public class BaseController : ApiController { } }
UserController.cs
using System.Net; using System.Web.Http; namespace SSLWebApi.Controllers { [RoutePrefix("api/User")] public class UserController : BaseController { /// <summary> /// 獲取當前用戶信息 /// </summary> /// <param name="msg"></param> /// <returns></returns> [HttpPost] [Route("PostMessage")] public string PostMessage([FromBody]string msg) { return string.Format("當前輸入的消息是:{0}", msg); } [Route("GetMachine")] public string GetMachine() { string AddressIP = string.Empty; foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList) { if (_IPAddress.AddressFamily.ToString() == "InterNetwork") { AddressIP = _IPAddress.ToString(); } } return string.Format("當前WebApi部署的IP是:{0}", AddressIP); } } }
客戶端:
Program.cs
using System; using System.IO; using System.Net; using System.Text; namespace SSLWebApiClient { class Program { static void Main(string[] args) { for (int i = 0; i < 10; i++) { //https協議基本認證 Authorization string url = "https://zhyongfeng.com/api/user/GetMachine"; ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); NetworkCredential credential = new NetworkCredential("zhyongfeng", "123456"); req.Credentials = credential; HttpWebResponse response = (HttpWebResponse)req.GetResponse(); Stream responseStream = response.GetResponseStream(); StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); string html = streamReader.ReadToEnd(); Console.WriteLine(html); } Console.Read(); } } }
6 部署WebApi到區域網內3台PC機
將WebApi部署到以下10.92.202.56的3台PC機
7 Nginx集群配置搭建
通過自主義功能變數名稱zhyongfeng.com:80埠進行負載均衡集群訪問,則訪問C:\Windows\System32\drivers\etc\hosts,添加下列“本機IP 自定義的功能變數名稱”:
10.93.85.66 zhyongfeng.com
Nginx的集群配置:
#user nobody; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #server { # listen 80; # server_name localhost; # location / { # root html; # index index.html index.htm; # } # error_page 500 502 503 504 /50x.html; # location = /50x.html { # root html; # } #} upstream zhyongfeng.com { server 10.92.202.56:560; server 10.92.202.57:570; server 10.92.202.58:580; } server { listen 80; server_name zhyongfeng.com; rewrite ^(.*)$ https://$host$1 permanent; } # HTTPS server # server { listen 443 ssl; server_name zhyongfeng.com; ssl_certificate server.crt; ssl_certificate_key server_nopass.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; location / { proxy_pass http://zhyongfeng.com; } } }
運行CMD:
D:\DTLDownLoads\nginx-1.10.2>start nginx
D:\DTLDownLoads\nginx-1.10.2>nginx -s reload
8 運行結果
直接訪問功能變數名稱運行結果:
SOAP UI調用運行結果:
啟動客戶端,通過身份驗證運行結果如下:
9 總結
在HTTP協議進行通信的過程中,HTTP協議定義了基本認證過程以允許HTTP伺服器對WEB瀏覽器進行用戶身份證的方法,當一個客戶端向HTTP服務 器進行數據請求時,如果客戶端未被認證,則HTTP伺服器將通過基本認證過程對客戶端的用戶名及密碼進行驗證,以決定用戶是否合法。客戶端在接收到HTTP伺服器的身份認證要求後,會提示用戶輸入用戶名及密碼,然後將用戶名及密碼以BASE64加密。
Nginx基於SSL協議下,利用http basic身份驗證,可以實現簡單訪問WebApi,達到集群負載均衡的效果。通過簡單的設計,在區域網上應用還是夠用的。當然,身份認證方式有很多種,使用redis、token都是可以的。WebApi基於SSL協議數據傳輸加密,結合http basic在一定上保證了通信的安全性。
源代碼下載:
http://download.csdn.net/download/ruby_matlab/10141134
PDF下載: