亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

使用ASP.NET Web Api構建基于REST風格的服務實戰系列教程【八】——Web Api的安全性

2019-11-15 02:30:41
字體:
來源:轉載
供稿:網友

使用asp.net Web Api構建基于REST風格的服務實戰系列教程【八】——Web Api的安全性

系列導航地址http://www.49028c.com/fzrain/p/3490137.html

前言

這一篇文章我們主要來探討一下Web Api的安全性,到目前為止所有的請求都是走的Http協議(http://),因此客戶端與服務器之間的通信是沒有加密的。在本篇中,我們將在“StudentController”中添加身份驗證功能——通過驗證用戶名與密碼來判斷是否是合法用戶。眾所周知,對于機密信息的傳遞,我們應該使用安全的Http協議(https://)來傳輸

在Web Api中強制使用Https

我們可以在IIS級別配置整個Web Api來強制使用Https,但是在某些情況下你可能只需要對某一個action強制使用Https,而其他的方法仍使用http。

為了實現這一點,我們將使用Web Api中的filters——filter(過濾器)的主要作用就是可以在我們執行方法之前執行一段代碼。沒接觸過得可以通過下圖簡單理解下,大神跳過:

無標題

我們新創建的filter將用來檢測是否是安全的,如果不是安全的,filter將終止請求并返回相應:請求必須是https。

具體做法:創建一個filter繼承自AuthorizationFilterAttribute,重寫OnAuthorization來實現我們的需求。

在網站根目錄下創建“Filters”文件夾,新建一個類“ForceHttpsAttribute”繼承自“System.Web.Http.Filters.AuthorizationFilterAttribute”,下面上代碼:

public class ForceHttpsAttribute : AuthorizationFilterAttribute    {        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)        {            var request = actionContext.Request;             if (request.RequestUri.Scheme != Uri.UriSchemeHttps)            {                var html = "<p>Https is required</p>";                 if (request.Method.Method == "GET")                {                    actionContext.Response = request.CreateResponse(HttpStatusCode.Found);                    actionContext.Response.Content = new StringContent(html, Encoding.UTF8, "text/html");                     UriBuilder httpsNewUri = new UriBuilder(request.RequestUri);                    httpsNewUri.Scheme = Uri.UriSchemeHttps;                    httpsNewUri.Port = 443;                     actionContext.Response.Headers.Location = httpsNewUri.Uri;                }                else                {                    actionContext.Response = request.CreateResponse(HttpStatusCode.NotFound);                    actionContext.Response.Content = new StringContent(html, Encoding.UTF8, "text/html");                }             }        }    }

在上面代碼中,我們通過actionContext參數拿到request和response對象,我們判斷客戶端的請求:如果不是https,那么直接響應客戶端應該使用https。

在這里,我們需要區分請求是Get還是其他(Post,Delete,Put),因為對于使用了Http的Get請求來訪問資源,我們將使用https創建一個連接并添加在響應Header的Location中。這樣做了之后客戶端就會自動使用https來發送Get請求了。

對于非Get請求,直接返回404,并通知客戶端必須使用https來請求

如果我們打算在整個項目中使用,那么在“WebAPIConfig”類中做如下設置:

public static void Register(HttpConfiguration config)   {       config.Filters.Add(new ForceHttpsAttribute());   }

如果我們相對具體的Controller或Action設置時,可以做如下設置:

//對于整個Controller強制使用Https
[Learning.Web.Filters.ForceHttps()]    public class CoursesController : BaseApiController    {    //僅對這個方法強制使用Https
        [Learning.Web.Filters.ForceHttps()]            public HttPResponseMessage Post([FromBody] CourseModel courseModel)            {         }}

使用Basic Authentication驗證用戶

到目前為止,我們提供的所有Api都是公開的,任何人都能訪問。但在真是場景中卻是不可取的,對于某些數據,只有通過認證的用戶才能訪問,我們這里有兩個地方恰好說明這一點:

1.當客戶端發送Get請求道“http://{your_port}/api/students/{userName}“的時候.例如:通過上述URI訪問userNme為“TaiseerJoudeh”的信息時,我們必須讓客戶端提供TaiseerJoudeh相應的用戶名和密碼,對于沒有提供驗證信息的用戶我們就不讓訪問,因為學生信息包含一些重要的私人信息(email,birthday等)。

2.當客戶端發送Post請求到“http://{your_port}/api/courses/2/students/{userName}“的時候,這意味著給學生選課,我們可以想一下,這里如果不做驗證,那么所有人都能隨便給某個學生選課,那么不就亂了么。

對于上面的場景,我們使用Basic Authentication來進行身份驗證,主要思路是使用filter從請求header部分獲取身份信息,校驗驗證類型是否為“basic”,然后校驗內容,正確就放行,否則返回401 (Unauthorized)狀態碼。

在上代碼前,解釋一下下basic authentication:

什么是basic authentication?

它意味著在正式處理Http請求之前對請求者身份的校驗,這可以防止服務器受到DoS攻擊(Denial of service attacks)。原理是:客戶端在發送Http請求的時候在Header部分提供一個基于Base64編碼的用戶名和密碼,形式為“username:passWord”,消息接收者(服務器)進行驗證,通過后繼續處理請求。

由于用戶名和密碼僅適用base64編碼,因此為了保證安全性,basic authentication通常是基于SSL連接(https)

為了在我們的api中使用,創建一個類“LearningAuthorizeAttribute”繼承自System.Web.Http.Filters.AuthorizationFilterAttribute

public class LearningAuthorizeAttribute : AuthorizationFilterAttribute    {         [Inject]        public LearningRepository TheRepository { get; set; }         public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)        {            //forms authentication Case that user is authenticated using forms authentication
//so no need to check header for basic authentication.            if (Thread.CurrentPrincipal.Identity.IsAuthenticated)            {                return;            }             var authHeader = actionContext.Request.Headers.Authorization;             if (authHeader != null)            {                if (authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) &&                    !String.IsNullOrWhiteSpace(authHeader.Parameter))                {                    var credArray = GetCredentials(authHeader);                    var userName = credArray[0];                    var password = credArray[1];                     if (IsResourceOwner(userName, actionContext))                    {                        //You can use Websecurity or asp.net memebrship provider to login, for                        //for he sake of keeping example simple, we used out own login functionality                        if (TheRepository.LoginStudent(userName, password))                        {                            var currentPrincipal = new GenericPrincipal(new GenericIdentity(userName), null);                            Thread.CurrentPrincipal = currentPrincipal;                            return;                        }                    }                }            }             HandleUnauthorizedRequest(actionContext);        }         private string[] GetCredentials(System.Net.Http.Headers.AuthenticationHeaderValue authHeader)        {             //Base 64 encoded string            var rawCred = authHeader.Parameter;            var encoding = Encoding.GetEncoding("iso-8859-1");            var cred = encoding.GetString(Convert.FromBase64String(rawCred));             var credArray = cred.Split(':');             return credArray;        }         private bool IsResourceOwner(string userName, System.Web.Http.Controllers.HttpActionContext actionContext)        {            var routeData = actionContext.Request.GetRouteData();            var resourceUserName = routeData.Values["userName"] as string;             if (resourceUserName == userName)            {                return true;            }            return false;        }         private void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)        {            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);             actionContext.Response.Headers.Add("WWW-Authenticate",                                               "Basic Scheme='eLearning' location='http://localhost:8323/account/login'");         }    }

我們重寫了“OnAuthorization”,實現如下功能:

1.從請求Header中獲取校驗數據

2.判斷驗證信息類型為“basic”并包含base64編碼

3.將base64編碼轉化為string,并提取用戶名和密碼

4.校驗提供的驗證信息是否與訪問的資源信息相同(學生的詳細信息只能由他自己訪問)

5.去數據庫校驗用戶名及密碼

6.如果校驗通過,則設置Thread的CurrentPrincipal,使本次接下來的請求都是通過校驗的。

7.校驗沒通過,返回401(Unauthorized)并添加一個WWW-Authenticate響應頭,根據這個請求,客戶端可以添加相應的驗證信息

在代碼中實現起來就很簡單了,上兩個Attribute就完了:

public class StudentsController : BaseApiController    {        [LearningAuthorizeAttribute]        public HttpResponseMessage Get(string userName)            {             }    }
public class EnrollmentsController : BaseApiController    {        [LearningAuthorizeAttribute]        public HttpResponseMessage Post(int courseId, [FromUri]string userName, [FromBody]Enrollment enrollment)            {             }    }

測試成果

使用測試工具發送如下請求:

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
青草青草久热精品视频在线网站| 亚洲成人av片在线观看| 狠狠躁18三区二区一区| 欧美成人h版在线观看| 日韩av一区二区在线观看| 69av成年福利视频| 国产精品精品久久久久久| 亚洲免费视频网站| 日韩电影大全免费观看2023年上| 日韩精品在线免费观看视频| 精品国产一区二区三区久久久狼| 中文字幕在线视频日韩| 中文综合在线观看| 秋霞av国产精品一区| 日韩大片在线观看视频| 国产成人精品综合久久久| 成人免费淫片aa视频免费| 亚洲精品国精品久久99热| 久久在线免费观看视频| 欧美天堂在线观看| 91日本视频在线| 插插插亚洲综合网| 日本午夜在线亚洲.国产| 国产精品欧美日韩一区二区| 91av福利视频| 亚洲第一视频网| 欧美亚洲视频在线看网址| 精品亚洲va在线va天堂资源站| 久久久精品一区二区| 国产精品亚洲自拍| 亚洲欧美另类在线观看| 欧美一区二区三区四区在线| 欧美日韩xxxxx| 亚洲欧洲在线看| 国产精品美女久久| 韩国美女主播一区| 欧美成人三级视频网站| 黑人巨大精品欧美一区二区一视频| 欧美精品少妇videofree| 日韩精品视频在线| 亚洲欧美一区二区激情| 亚洲精品在线91| 日韩av电影在线播放| 国内精品小视频在线观看| 精品中文视频在线| 日韩理论片久久| 91九色综合久久| 国产精品露脸av在线| 欧美视频在线视频| 中文字幕国产日韩| 亚洲国产精品成人一区二区| 欧美性猛交xxx| 久久久精品影院| 亚洲成人av资源网| 国产成人短视频| 久久综合九色九九| 亚洲人午夜精品免费| 久久中文字幕在线| 69精品小视频| 国产一区二区三区直播精品电影| 福利视频导航一区| 国产美女精彩久久| 欧美在线中文字幕| 日韩极品精品视频免费观看| 久久精品久久久久久国产 免费| 88xx成人精品| 久久韩国免费视频| 久久久久国产视频| 亚洲天堂av网| 成人激情视频在线播放| 亚洲一区二区三区香蕉| 欧亚精品中文字幕| 国产精品久久久久一区二区| 欧美一级免费看| 精品国产欧美一区二区三区成人| 亚洲精品国产精品国自产观看浪潮| 亚洲xxxx做受欧美| 91色精品视频在线| 精品人伦一区二区三区蜜桃免费| 国产精品成人久久久久| 中文字幕亚洲情99在线| 亚洲高清av在线| 51视频国产精品一区二区| 亚洲全黄一级网站| 91精品国产91久久久久| 91在线网站视频| 亚洲视频在线观看免费| 精品亚洲一区二区三区四区五区| 97国产suv精品一区二区62| 色爱av美腿丝袜综合粉嫩av| 欧美一级片一区| 久久精品国产视频| 欧美日韩在线看| 亚洲成人免费在线视频| 亚洲免费小视频| 成人黄色片在线| 日韩av在线一区二区| 国产日本欧美一区| 久久国产精品首页| 亚洲欧美国产精品va在线观看| 国产亚洲精品美女久久久久| 亚洲无限乱码一二三四麻| 国内揄拍国内精品少妇国语| 日韩精品在线观看一区二区| 欧美一区二区.| 中日韩美女免费视频网站在线观看| 国产欧亚日韩视频| 中文字幕视频一区二区在线有码| 国产精品高潮视频| 国产成人欧美在线观看| 一区二区在线视频播放| 久久久女女女女999久久| 亚洲欧美国产日韩中文字幕| 日韩精品中文字幕在线播放| 欧美高清videos高潮hd| 欧美性xxxx极品高清hd直播| 2019中文字幕在线免费观看| 日本久久亚洲电影| 亚洲视频欧洲视频| 国产精品免费观看在线| 国产有码在线一区二区视频| 亚洲精品免费网站| 日韩女在线观看| 91欧美视频网站| 成人黄色短视频在线观看| 欧美劲爆第一页| 久久97久久97精品免视看| 国产成人avxxxxx在线看| 人妖精品videosex性欧美| 日本韩国在线不卡| 国产日韩欧美91| 性亚洲最疯狂xxxx高清| 国产精品白丝av嫩草影院| 欧美国产亚洲视频| 亚洲老头老太hd| 97在线视频观看| 韩国三级日本三级少妇99| 色偷偷亚洲男人天堂| 7777kkkk成人观看| 精品国产电影一区| 亚洲国产日韩一区| 国产精品盗摄久久久| 亚洲自拍小视频免费观看| 亚洲日本欧美中文幕| 亚洲无亚洲人成网站77777| 91wwwcom在线观看| 在线看日韩av| 欧美高清性猛交| 国产精品免费久久久| 国产日韩综合一区二区性色av| 国产福利精品av综合导导航| 久久91亚洲精品中文字幕奶水| 理论片在线不卡免费观看| 国产精品欧美一区二区三区奶水| 日本91av在线播放| 97国产一区二区精品久久呦| 亚洲国产精品热久久| 中文字幕视频在线免费欧美日韩综合在线看| 欧美最猛性xxxxx亚洲精品| 2025国产精品视频| 亚洲国产欧美一区二区丝袜黑人| 97香蕉超级碰碰久久免费软件| 亚洲欧美另类自拍| 欧美激情第1页|