日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WebApi权限验证流程的设计和实现

發(fā)布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WebApi权限验证流程的设计和实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言:Web 用戶的身份驗證,及頁面操作權限驗證是B/S系統(tǒng)的基礎功能,一個功能復雜的業(yè)務應用系統(tǒng),通過角色授權來控制用戶訪問,本文通過Form認證,Mvc的Controller基類及Action的權限驗證來實現(xiàn)Web系統(tǒng)登錄,Mvc前端權限校驗以及WebApi服務端的訪問校驗功能。

?

1. Web Form認證介紹

Web應用的訪問方式因為是基于瀏覽器的Http地址請求,所以需要驗證用戶身份的合法性。目前常見的方式是Form認證,其處理邏輯描述如下:
1. 用戶首先要在登錄頁面輸入用戶名和密碼,然后登錄系統(tǒng),獲取合法身份的票據(jù),再執(zhí)行后續(xù)業(yè)務處理操作;
2. 用戶在沒有登錄的情況下提交Http頁面訪問請求,如果該頁面不允許匿名訪問,則直接跳轉到登錄頁面;
3. 對于允許匿名訪問的頁面請求,系統(tǒng)不做權限驗證,直接處理業(yè)務數(shù)據(jù),并返回給前端;
4. 對于不同權限要求的頁面Action操作,系統(tǒng)需要校驗用戶角色,計算權限列表,如果請求操作在權限列表中,則正常訪問,如果不在權限列表中,則提示“未授權的訪問操作”到異常處理頁面。

?

2. WebApi 服務端Basic 方式驗證

WebApi服務端接收訪問請求,需要做安全驗證處理,驗證處理步驟如下:
1. 如果是合法的Http請求,在Http請求頭中會有用戶身份的票據(jù)信息,服務端會讀取票據(jù)信息,并校驗票據(jù)信息是否完整有效,如果滿足校驗要求,則進行業(yè)務數(shù)據(jù)的處理,并返回給請求發(fā)起方;
2. 如果沒有票據(jù)信息,或者票據(jù)信息不是合法的,則返回“未授權的訪問”異常消息給前端,由前端處理此異常。

?

3. 登錄及權限驗證流程

流程處理步驟說明:
1. 用戶打開瀏覽器,并在地址欄中輸入頁面請求地址,提交;
2. 瀏覽器解析Http請求,發(fā)送到Web服務器;Web服務器驗證用戶請求,首先判斷是否有登錄的票據(jù)信息;
3. 用戶沒有登錄票據(jù)信息,則跳轉到登錄頁面;
4. 用戶輸入用戶名和密碼信息;
5. 瀏覽器提交登錄表單數(shù)據(jù)給Web服務器;
6. Web服務需要驗證用戶名和密碼是否匹配,發(fā)送api請求給api服務器;
7. api用戶賬戶服務根據(jù)用戶名,讀取存儲在數(shù)據(jù)庫中的用戶資料,判斷密碼是否匹配;
1)如果用戶名和密碼不匹配,則提示密碼錯誤等信息,然該用戶重新填寫登錄資料;
2)如果驗證通過,則保存用戶票據(jù)信息;
8. 接第3步,如果用戶有登錄票據(jù)信息,則跳轉到用戶請求的頁面;
9. 驗證用戶對當前要操作的頁面或頁面元素是否有權限操作,首先需要發(fā)起api服務請求,獲取用戶的權限數(shù)據(jù);
10. api用戶權限服務根據(jù)用戶名,查找該用戶的角色信息,并計算用戶權限列表,封裝為Json數(shù)據(jù)并返回;
11. 當用戶有權限操作頁面或頁面元素時,跳轉到頁面,并由頁面Controller提交業(yè)務數(shù)據(jù)處理請求到api服務器;
? ?如果用戶沒有權限訪問該頁面或頁面元素時,則顯示“未授權的訪問操作”,跳轉到系統(tǒng)異常處理頁面。
12. api業(yè)務服務處理業(yè)務邏輯,并將結果以Json 數(shù)據(jù)返回;
13. 返回渲染后的頁面給瀏覽器前端,并呈現(xiàn)業(yè)務數(shù)據(jù)到頁面;
14. 用戶填寫業(yè)務數(shù)據(jù),或者查找業(yè)務數(shù)據(jù);
15. 當填寫或查找完業(yè)務數(shù)據(jù)后,用戶提交表單數(shù)據(jù);
16. 瀏覽器腳本提交get,post等請求給web服務器,由web服務器再次解析請求操作,重復步驟2的后續(xù)流程;
17. 當api服務器驗證用戶身份是,沒有可信用戶票據(jù),系統(tǒng)提示“未授權的訪問操作”,跳轉到系統(tǒng)異常處理頁面。

?

4. Mvc前端代碼示例

4.1 用戶登錄AccountController

[csharp]?view plaincopy
  • <span?style="font-size:?18px;">?</span><span?style="font-size:?14px;">
  • public?class?AccountController?:?Controller??
  • ????{??
  • ????????//??
  • ????????//?GET:?/Logon/??
  • ??
  • ????????public?ActionResult?Login(string?returnUrl)??
  • ????????{??
  • ????????????ViewBag.ReturnUrl?=?returnUrl;??
  • ????????????return?View();??
  • ????????}??
  • ??
  • ????????[HttpPost]??
  • ????????public?ActionResult?Logon(LoginUser?loginUser,?string?returnUrl)??
  • ????????{??
  • ????????????string?strUserName?=?loginUser.UserName;??
  • ????????????string?strPassword?=?loginUser.Password;??
  • ????????????var?accountModel?=?new?AccountModel();??
  • ??
  • ????????????//驗證用戶是否是系統(tǒng)注冊用戶??
  • ????????????if?(accountModel.ValidateUserLogin(strUserName,?strPassword))??
  • ????????????{??
  • ????????????????if?(Url.IsLocalUrl(returnUrl))??
  • ????????????????{??
  • ????????????????????//創(chuàng)建用戶ticket信息??
  • ????????????????????accountModel.CreateLoginUserTicket(strUserName,?strPassword);??
  • ??
  • ????????????????????//讀取用戶權限數(shù)據(jù)??
  • ????????????????????accountModel.GetUserAuthorities(strUserName);??
  • ??
  • ????????????????????return?new?RedirectResult(returnUrl);??
  • ????????????????}??
  • ????????????????else??
  • ????????????????{??
  • ????????????????????return?RedirectToAction("Index",?"Home");??
  • ????????????????}?????????????????
  • ????????????}??
  • ????????????else??
  • ????????????{??
  • ????????????????throw?new?ApplicationException("無效登錄用戶!");??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?用戶注銷,注銷之前,清除用戶ticket??
  • ????????///?</summary>??
  • ????????///?<returns></returns>??
  • ????????[HttpPost]??
  • ????????public?ActionResult?Logout()??
  • ????????{??
  • ????????????var?accountModel?=?new?AccountModel();??
  • ????????????accountModel.Logout();??
  • ??
  • ????????????return?RedirectToAction("Login",?"Account");??
  • ????????}??
  • ????}</span>??
  • [csharp]?view plaincopy
  • <span?style="font-size:18px;">?</span><span?style="font-size:14px;">public?class?AccountController?:?Controller??
  • ????{??
  • ????????//??
  • ????????//?GET:?/Logon/??
  • ??
  • ????????public?ActionResult?Login(string?returnUrl)??
  • ????????{??
  • ????????????ViewBag.ReturnUrl?=?returnUrl;??
  • ????????????return?View();??
  • ????????}??
  • ??
  • ????????[HttpPost]??
  • ????????public?ActionResult?Logon(LoginUser?loginUser,?string?returnUrl)??
  • ????????{??
  • ????????????string?strUserName?=?loginUser.UserName;??
  • ????????????string?strPassword?=?loginUser.Password;??
  • ????????????var?accountModel?=?new?AccountModel();??
  • ??
  • ????????????//驗證用戶是否是系統(tǒng)注冊用戶??
  • ????????????if?(accountModel.ValidateUserLogin(strUserName,?strPassword))??
  • ????????????{??
  • ????????????????if?(Url.IsLocalUrl(returnUrl))??
  • ????????????????{??
  • ????????????????????//創(chuàng)建用戶ticket信息??
  • ????????????????????accountModel.CreateLoginUserTicket(strUserName,?strPassword);??
  • ??
  • ????????????????????//讀取用戶權限數(shù)據(jù)??
  • ????????????????????accountModel.GetUserAuthorities(strUserName);??
  • ??
  • ????????????????????return?new?RedirectResult(returnUrl);??
  • ????????????????}??
  • ????????????????else??
  • ????????????????{??
  • ????????????????????return?RedirectToAction("Index",?"Home");??
  • ????????????????}?????????????????
  • ????????????}??
  • ????????????else??
  • ????????????{??
  • ????????????????throw?new?ApplicationException("無效登錄用戶!");??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?用戶注銷,注銷之前,清除用戶ticket??
  • ????????///?</summary>??
  • ????????///?<returns></returns>??
  • ????????[HttpPost]??
  • ????????public?ActionResult?Logout()??
  • ????????{??
  • ????????????var?accountModel?=?new?AccountModel();??
  • ????????????accountModel.Logout();??
  • ??
  • ????????????return?RedirectToAction("Login",?"Account");??
  • ????????}??
  • ????}</span>??
  • ?

    4.2 用戶模型AccountModel

    [csharp]?view plaincopy
  • <span?style="font-size:?14px;">
  • public?class?AccountModel??
  • ????{??
  • ????????///?<summary>??
  • ????????///?創(chuàng)建登錄用戶的票據(jù)信息??
  • ????????///?</summary>??
  • ????????///?<param?name="strUserName"></param>??
  • ????????internal?void?CreateLoginUserTicket(string?strUserName,?string?strPassword)??
  • ????????{??
  • ????????????//構造Form驗證的票據(jù)信息??
  • ????????????FormsAuthenticationTicket?ticket?=?new?FormsAuthenticationTicket(1,?strUserName,?DateTime.Now,?DateTime.Now.AddMinutes(90),??
  • ????????????????true,?string.Format("{0}:{1}",?strUserName,?strPassword),?FormsAuthentication.FormsCookiePath);??
  • ??
  • ????????????string?ticString?=?FormsAuthentication.Encrypt(ticket);??
  • ??
  • ????????????//把票據(jù)信息寫入Cookie和Session??
  • ????????????//SetAuthCookie方法用于標識用戶的Identity狀態(tài)為true??
  • ????????????HttpContext.Current.Response.Cookies.Add(new?HttpCookie(FormsAuthentication.FormsCookieName,?ticString));??
  • ????????????FormsAuthentication.SetAuthCookie(strUserName,?true);??
  • ????????????HttpContext.Current.Session["USER_LOGON_TICKET"]?=?ticString;??
  • ??????????????
  • ????????????//重寫HttpContext中的用戶身份,可以封裝自定義角色數(shù)據(jù);??
  • ????????????//判斷是否合法用戶,可以檢查:HttpContext.User.Identity.IsAuthenticated的屬性值??
  • ????????????string[]?roles?=?ticket.UserData.Split(',');??
  • ????????????IIdentity?identity?=?new?FormsIdentity(ticket);??
  • ????????????IPrincipal?principal?=?new?GenericPrincipal(identity,?roles);??
  • ????????????HttpContext.Current.User?=?principal;??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?獲取用戶權限列表數(shù)據(jù)??
  • ????????///?</summary>??
  • ????????///?<param?name="userName"></param>??
  • ????????///?<returns></returns>??
  • ????????internal?string?GetUserAuthorities(string?userName)??
  • ????????{??
  • ????????????//從WebApi?訪問用戶權限數(shù)據(jù),然后寫入Session??
  • ????????????string?jsonAuth?=?"[{\"Controller\":?\"SampleController\",?\"Actions\":\"Apply,Process,Complete\"},?{\"Controller\":?\"Product\",?\"Actions\":?\"List,Get,Detail\"}]";??
  • ????????????var?userAuthList?=?ServiceStack.Text.JsonSerializer.DeserializeFromString(jsonAuth,?typeof(UserAuthModel[]));??
  • ????????????HttpContext.Current.Session["USER_AUTHORITIES"]?=?userAuthList;??
  • ??
  • ????????????return?jsonAuth;??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?讀取數(shù)據(jù)庫用戶表數(shù)據(jù),判斷用戶密碼是否匹配??
  • ????????///?</summary>??
  • ????????///?<param?name="name"></param>??
  • ????????///?<param?name="password"></param>??
  • ????????///?<returns></returns>??
  • ????????internal?bool?ValidateUserLogin(string?name,?string?password)??
  • ????????{??
  • ????????????//bool?isValid?=?password?==?passwordInDatabase;??
  • ????????????return?true;??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?用戶注銷執(zhí)行的操作??
  • ????????///?</summary>??
  • ????????internal?void?Logout()??
  • ????????{??
  • ????????????FormsAuthentication.SignOut();??
  • ????????}??
  • ????}</span>??
  • [csharp]?view plaincopy
  • <span?style="font-size:14px;">public?class?AccountModel??
  • ????{??
  • ????????///?<summary>??
  • ????????///?創(chuàng)建登錄用戶的票據(jù)信息??
  • ????????///?</summary>??
  • ????????///?<param?name="strUserName"></param>??
  • ????????internal?void?CreateLoginUserTicket(string?strUserName,?string?strPassword)??
  • ????????{??
  • ????????????//構造Form驗證的票據(jù)信息??
  • ????????????FormsAuthenticationTicket?ticket?=?new?FormsAuthenticationTicket(1,?strUserName,?DateTime.Now,?DateTime.Now.AddMinutes(90),??
  • ????????????????true,?string.Format("{0}:{1}",?strUserName,?strPassword),?FormsAuthentication.FormsCookiePath);??
  • ??
  • ????????????string?ticString?=?FormsAuthentication.Encrypt(ticket);??
  • ??
  • ????????????//把票據(jù)信息寫入Cookie和Session??
  • ????????????//SetAuthCookie方法用于標識用戶的Identity狀態(tài)為true??
  • ????????????HttpContext.Current.Response.Cookies.Add(new?HttpCookie(FormsAuthentication.FormsCookieName,?ticString));??
  • ????????????FormsAuthentication.SetAuthCookie(strUserName,?true);??
  • ????????????HttpContext.Current.Session["USER_LOGON_TICKET"]?=?ticString;??
  • ??????????????
  • ????????????//重寫HttpContext中的用戶身份,可以封裝自定義角色數(shù)據(jù);??
  • ????????????//判斷是否合法用戶,可以檢查:HttpContext.User.Identity.IsAuthenticated的屬性值??
  • ????????????string[]?roles?=?ticket.UserData.Split(',');??
  • ????????????IIdentity?identity?=?new?FormsIdentity(ticket);??
  • ????????????IPrincipal?principal?=?new?GenericPrincipal(identity,?roles);??
  • ????????????HttpContext.Current.User?=?principal;??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?獲取用戶權限列表數(shù)據(jù)??
  • ????????///?</summary>??
  • ????????///?<param?name="userName"></param>??
  • ????????///?<returns></returns>??
  • ????????internal?string?GetUserAuthorities(string?userName)??
  • ????????{??
  • ????????????//從WebApi?訪問用戶權限數(shù)據(jù),然后寫入Session??
  • ????????????string?jsonAuth?=?"[{\"Controller\":?\"SampleController\",?\"Actions\":\"Apply,Process,Complete\"},?{\"Controller\":?\"Product\",?\"Actions\":?\"List,Get,Detail\"}]";??
  • ????????????var?userAuthList?=?ServiceStack.Text.JsonSerializer.DeserializeFromString(jsonAuth,?typeof(UserAuthModel[]));??
  • ????????????HttpContext.Current.Session["USER_AUTHORITIES"]?=?userAuthList;??
  • ??
  • ????????????return?jsonAuth;??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?讀取數(shù)據(jù)庫用戶表數(shù)據(jù),判斷用戶密碼是否匹配??
  • ????????///?</summary>??
  • ????????///?<param?name="name"></param>??
  • ????????///?<param?name="password"></param>??
  • ????????///?<returns></returns>??
  • ????????internal?bool?ValidateUserLogin(string?name,?string?password)??
  • ????????{??
  • ????????????//bool?isValid?=?password?==?passwordInDatabase;??
  • ????????????return?true;??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?用戶注銷執(zhí)行的操作??
  • ????????///?</summary>??
  • ????????internal?void?Logout()??
  • ????????{??
  • ????????????FormsAuthentication.SignOut();??
  • ????????}??
  • ????}</span>??


  • 4.3 控制器基類WebControllerBase

    [csharp]?view plaincopy
  • <span?style="font-size:?14px;">///?<summary>??
  • ????///?前端Mvc控制器基類??
  • ????///?</summary>??
  • ????[Authorize]??
  • ????public?abstract?class?WebControllerBase?:?Controller??
  • ????{??
  • ????????///?<summary>??
  • ????????///?對應api的Url??
  • ????????///?</summary>??
  • ????????public?string?ApiUrl??
  • ????????{??
  • ????????????get;??
  • ????????????protected?set;??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?用戶權限列表??
  • ????????///?</summary>??
  • ????????public?UserAuthModel[]?UserAuthList??
  • ????????{??
  • ????????????get??
  • ????????????{??
  • ????????????????return?AuthorizedUser.Current.UserAuthList;??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?登錄用戶票據(jù)??
  • ????????///?</summary>??
  • ????????public?string?UserLoginTicket??
  • ????????{??
  • ????????????get??
  • ????????????{??
  • ????????????????return?AuthorizedUser.Current.UserLoginTicket;??
  • ????????????}??
  • ????????}??
  • ????}</span>??
  • [csharp]?view plaincopy
  • <span?style="font-size:14px;">///?<summary>??
  • ????///?前端Mvc控制器基類??
  • ????///?</summary>??
  • ????[Authorize]??
  • ????public?abstract?class?WebControllerBase?:?Controller??
  • ????{??
  • ????????///?<summary>??
  • ????????///?對應api的Url??
  • ????????///?</summary>??
  • ????????public?string?ApiUrl??
  • ????????{??
  • ????????????get;??
  • ????????????protected?set;??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?用戶權限列表??
  • ????????///?</summary>??
  • ????????public?UserAuthModel[]?UserAuthList??
  • ????????{??
  • ????????????get??
  • ????????????{??
  • ????????????????return?AuthorizedUser.Current.UserAuthList;??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?登錄用戶票據(jù)??
  • ????????///?</summary>??
  • ????????public?string?UserLoginTicket??
  • ????????{??
  • ????????????get??
  • ????????????{??
  • ????????????????return?AuthorizedUser.Current.UserLoginTicket;??
  • ????????????}??
  • ????????}??
  • ????}</span>??
  • ?

    4.4 權限屬性RequireAuthorizationAttribute

    [csharp]?view plaincopy
  • <span?style="font-size:?14px;">///?<summary>??
  • ????///?權限驗證屬性類??
  • ????///?</summary>??
  • ????public?class?RequireAuthorizeAttribute?:?AuthorizeAttribute??
  • ????{??
  • ????????///?<summary>??
  • ????????///?用戶權限列表??
  • ????????///?</summary>??
  • ????????public?UserAuthModel[]?UserAuthList??
  • ????????{??
  • ????????????get??
  • ????????????{??
  • ????????????????return?AuthorizedUser.Current.UserAuthList;??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?登錄用戶票據(jù)??
  • ????????///?</summary>??
  • ????????public?string?UserLoginTicket??
  • ????????{??
  • ????????????get??
  • ????????????{??
  • ????????????????return?AuthorizedUser.Current.UserLoginTicket;??
  • ????????????}??
  • ????????}??
  • ??
  • ????????public?override?void?OnAuthorization(AuthorizationContext?filterContext)??
  • ????????{??
  • ????????????base.OnAuthorization(filterContext);??
  • ??
  • ????????????驗證是否是登錄用戶??
  • ????????????var?identity?=?filterContext.HttpContext.User.Identity;??
  • ????????????if?(identity.IsAuthenticated)??
  • ????????????{??
  • ????????????????var?actionName?=?filterContext.ActionDescriptor.ActionName;??
  • ????????????????var?controllerName?=?filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;??
  • ??
  • ????????????????//驗證用戶操作是否在權限列表中??
  • ????????????????if?(HasActionQulification(actionName,?controllerName,?identity.Name))??
  • ????????????????????if?(!string.IsNullOrEmpty(UserLoginTicket))??
  • ????????????????????????//有效登錄用戶,有權限訪問此Action,則寫入Cookie信息??
  • ????????????????????????filterContext.HttpContext.Response.Cookies[FormsAuthentication.FormsCookieName].Value?=?UserLoginTicket;??
  • ????????????????????else??
  • ????????????????????????//用戶的Session,?Cookie都過期,需要重新登錄??
  • ????????????????????????filterContext.HttpContext.Response.Redirect("~/Account/Login",?false);??
  • ????????????????else??
  • ????????????????????//雖然是登錄用戶,但沒有該Action的權限,跳轉到“未授權訪問”頁面??
  • ????????????????????filterContext.HttpContext.Response.Redirect("~/Home/UnAuthorized",?true);??
  • ????????????}??
  • ????????????else??
  • ????????????{??
  • ????????????????//未登錄用戶,則判斷是否是匿名訪問??
  • ????????????????var?attr?=?filterContext.ActionDescriptor.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>();??
  • ????????????????bool?isAnonymous?=?attr.Any(a?=>?a?is?AllowAnonymousAttribute);??
  • ??
  • ????????????????if?(!isAnonymous)??
  • ????????????????????//未驗證(登錄)的用戶,?而且是非匿名訪問,則轉向登錄頁面??
  • ????????????????????filterContext.HttpContext.Response.Redirect("~/Account/Login",?true);??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?從權限列表驗證用戶是否有權訪問Action??
  • ????????///?</summary>??
  • ????????///?<param?name="actionName"></param>??
  • ????????///?<param?name="controllerName"></param>??
  • ????????///?<returns></returns>??
  • ????????private?bool?HasActionQulification(string?actionName,?string?controllerName,?string?userName)??
  • ????????{??
  • ????????????//從該用戶的權限數(shù)據(jù)列表中查找是否有當前Controller和Action的item??
  • ????????????var?auth?=?UserAuthList.FirstOrDefault(a?=>??
  • ????????????{??
  • ????????????????bool?rightAction?=?false;??
  • ????????????????bool?rightController?=?a.Controller?==?controllerName;??
  • ????????????????if?(rightController)??
  • ????????????????{??
  • ????????????????????string[]?actions?=?a.Actions.Split(',');??
  • ????????????????????rightAction?=?actions.Contains(actionName);??
  • ????????????????}??
  • ????????????????return?rightAction;??
  • ????????????});??
  • ??
  • ????????????//此處可以校驗用戶的其它權限條件??
  • ????????????//var?notAllowed?=?HasOtherLimition(userName);??
  • ????????????//var?result?=?(auth?!=?null)?&&?notAllowed;??
  • ????????????//return?result;??
  • ??
  • ????????????return?(auth?!=?null);??
  • ????????}??
  • ????}</span>??
  • [csharp]?view plaincopy
  • <span?style="font-size:14px;">///?<summary>??
  • ????///?權限驗證屬性類??
  • ????///?</summary>??
  • ????public?class?RequireAuthorizeAttribute?:?AuthorizeAttribute??
  • ????{??
  • ????????///?<summary>??
  • ????????///?用戶權限列表??
  • ????????///?</summary>??
  • ????????public?UserAuthModel[]?UserAuthList??
  • ????????{??
  • ????????????get??
  • ????????????{??
  • ????????????????return?AuthorizedUser.Current.UserAuthList;??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?登錄用戶票據(jù)??
  • ????????///?</summary>??
  • ????????public?string?UserLoginTicket??
  • ????????{??
  • ????????????get??
  • ????????????{??
  • ????????????????return?AuthorizedUser.Current.UserLoginTicket;??
  • ????????????}??
  • ????????}??
  • ??
  • ????????public?override?void?OnAuthorization(AuthorizationContext?filterContext)??
  • ????????{??
  • ????????????base.OnAuthorization(filterContext);??
  • ??
  • ????????????驗證是否是登錄用戶??
  • ????????????var?identity?=?filterContext.HttpContext.User.Identity;??
  • ????????????if?(identity.IsAuthenticated)??
  • ????????????{??
  • ????????????????var?actionName?=?filterContext.ActionDescriptor.ActionName;??
  • ????????????????var?controllerName?=?filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;??
  • ??
  • ????????????????//驗證用戶操作是否在權限列表中??
  • ????????????????if?(HasActionQulification(actionName,?controllerName,?identity.Name))??
  • ????????????????????if?(!string.IsNullOrEmpty(UserLoginTicket))??
  • ????????????????????????//有效登錄用戶,有權限訪問此Action,則寫入Cookie信息??
  • ????????????????????????filterContext.HttpContext.Response.Cookies[FormsAuthentication.FormsCookieName].Value?=?UserLoginTicket;??
  • ????????????????????else??
  • ????????????????????????//用戶的Session,?Cookie都過期,需要重新登錄??
  • ????????????????????????filterContext.HttpContext.Response.Redirect("~/Account/Login",?false);??
  • ????????????????else??
  • ????????????????????//雖然是登錄用戶,但沒有該Action的權限,跳轉到“未授權訪問”頁面??
  • ????????????????????filterContext.HttpContext.Response.Redirect("~/Home/UnAuthorized",?true);??
  • ????????????}??
  • ????????????else??
  • ????????????{??
  • ????????????????//未登錄用戶,則判斷是否是匿名訪問??
  • ????????????????var?attr?=?filterContext.ActionDescriptor.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>();??
  • ????????????????bool?isAnonymous?=?attr.Any(a?=>?a?is?AllowAnonymousAttribute);??
  • ??
  • ????????????????if?(!isAnonymous)??
  • ????????????????????//未驗證(登錄)的用戶,?而且是非匿名訪問,則轉向登錄頁面??
  • ????????????????????filterContext.HttpContext.Response.Redirect("~/Account/Login",?true);??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?從權限列表驗證用戶是否有權訪問Action??
  • ????????///?</summary>??
  • ????????///?<param?name="actionName"></param>??
  • ????????///?<param?name="controllerName"></param>??
  • ????????///?<returns></returns>??
  • ????????private?bool?HasActionQulification(string?actionName,?string?controllerName,?string?userName)??
  • ????????{??
  • ????????????//從該用戶的權限數(shù)據(jù)列表中查找是否有當前Controller和Action的item??
  • ????????????var?auth?=?UserAuthList.FirstOrDefault(a?=>??
  • ????????????{??
  • ????????????????bool?rightAction?=?false;??
  • ????????????????bool?rightController?=?a.Controller?==?controllerName;??
  • ????????????????if?(rightController)??
  • ????????????????{??
  • ????????????????????string[]?actions?=?a.Actions.Split(',');??
  • ????????????????????rightAction?=?actions.Contains(actionName);??
  • ????????????????}??
  • ????????????????return?rightAction;??
  • ????????????});??
  • ??
  • ????????????//此處可以校驗用戶的其它權限條件??
  • ????????????//var?notAllowed?=?HasOtherLimition(userName);??
  • ????????????//var?result?=?(auth?!=?null)?&&?notAllowed;??
  • ????????????//return?result;??
  • ??
  • ????????????return?(auth?!=?null);??
  • ????????}??
  • ????}</span>??
  • ?

    4.5 業(yè)務Controller示例

    [csharp]?view plaincopy
  • <span?style="font-size:?14px;">
  • public?class?ProductController?:?WebControllerBase??
  • {??
  • ??
  • ????????[AllowAnonymous]??
  • ????????public?ActionResult?Query()??
  • ????????{??
  • ????????????return?View("ProductQuery");??
  • ????????}??
  • ??
  • ????????[HttpGet]??
  • ????????//[AllowAnonymous]??
  • ????????[RequireAuthorize]??
  • ????????public?ActionResult?Detail(string?id)??
  • ????????{??
  • ????????????var?cookie?=?HttpContext.Request.Cookies;??
  • ????????????string?url?=?base.ApiUrl?+?"/Get/"?+?id;??
  • ????????????HttpClient?httpClient?=?HttpClientHelper.Create(url,?base.UserLoginTicket);??
  • ??????????????
  • ????????????string?result?=?httpClient.GetString();??
  • ????????????var?model?=?JsonSerializer.DeserializeFromString<Product>(result);??
  • ????????????ViewData["PRODUCT_ADD_OR_EDIT"]?=?"E";??
  • ????????????return?View("ProductForm",?model);??
  • ????????}??
  • }</span>??
  • [csharp]?view plaincopy
  • <span?style="font-size:14px;">public?class?ProductController?:?WebControllerBase??
  • {??
  • ??
  • ????????[AllowAnonymous]??
  • ????????public?ActionResult?Query()??
  • ????????{??
  • ????????????return?View("ProductQuery");??
  • ????????}??
  • ??
  • ????????[HttpGet]??
  • ????????//[AllowAnonymous]??
  • ????????[RequireAuthorize]??
  • ????????public?ActionResult?Detail(string?id)??
  • ????????{??
  • ????????????var?cookie?=?HttpContext.Request.Cookies;??
  • ????????????string?url?=?base.ApiUrl?+?"/Get/"?+?id;??
  • ????????????HttpClient?httpClient?=?HttpClientHelper.Create(url,?base.UserLoginTicket);??
  • ??????????????
  • ????????????string?result?=?httpClient.GetString();??
  • ????????????var?model?=?JsonSerializer.DeserializeFromString<Product>(result);??
  • ????????????ViewData["PRODUCT_ADD_OR_EDIT"]?=?"E";??
  • ????????????return?View("ProductForm",?model);??
  • ????????}??
  • }</span>??


  • 5. ?WebApi 服務端代碼示例

    5.1 控制器基類ApiControllerBase

    [csharp]?view plaincopy
  • ///?<summary>??
  • ///?Controller的基類,用于實現(xiàn)適合業(yè)務場景的基礎功能??
  • ///?</summary>??
  • ///?<typeparam?name="T"></typeparam>??
  • [BasicAuthentication]??
  • public?abstract?class?ApiControllerBase?:?ApiController??
  • {??
  • ??
  • }??
  • [csharp]?view plaincopy
  • ///?<summary>??
  • ///?Controller的基類,用于實現(xiàn)適合業(yè)務場景的基礎功能??
  • ///?</summary>??
  • ///?<typeparam?name="T"></typeparam>??
  • [BasicAuthentication]??
  • public?abstract?class?ApiControllerBase?:?ApiController??
  • {??
  • ??
  • }??
  • ?

    ?

    5.2 權限屬性BaseAuthenticationAttribute

    [csharp]?view plaincopy
  • ///?<summary>??
  • ????///?基本驗證Attribtue,用以Action的權限處理??
  • ????///?</summary>??
  • ????public?class?BasicAuthenticationAttribute?:?ActionFilterAttribute??
  • ????{??
  • ????????///?<summary>??
  • ????????///?檢查用戶是否有該Action執(zhí)行的操作權限??
  • ????????///?</summary>??
  • ????????///?<param?name="actionContext"></param>??
  • ????????public?override?void?OnActionExecuting(HttpActionContext?actionContext)??
  • ????????{??
  • ????????????//檢驗用戶ticket信息,用戶ticket信息來自調(diào)用發(fā)起方??
  • ????????????if?(actionContext.Request.Headers.Authorization?!=?null)??
  • ????????????{??
  • ????????????????//解密用戶ticket,并校驗用戶名密碼是否匹配??
  • ????????????????var?encryptTicket?=?actionContext.Request.Headers.Authorization.Parameter;??
  • ????????????????if?(ValidateUserTicket(encryptTicket))??
  • ????????????????????base.OnActionExecuting(actionContext);??
  • ????????????????else??
  • ????????????????????actionContext.Response?=?new?HttpResponseMessage(HttpStatusCode.Unauthorized);?????????????????????
  • ????????????}??
  • ????????????else??
  • ????????????{??
  • ????????????????//檢查web.config配置是否要求權限校驗??
  • ????????????????bool?isRquired?=?(WebConfigurationManager.AppSettings["WebApiAuthenticatedFlag"].ToString()?==?"true");??
  • ????????????????if?(isRquired)??
  • ????????????????{??
  • ????????????????????//如果請求Header不包含ticket,則判斷是否是匿名調(diào)用??
  • ????????????????????var?attr?=?actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();??
  • ????????????????????bool?isAnonymous?=?attr.Any(a?=>?a?is?AllowAnonymousAttribute);??
  • ??
  • ????????????????????//是匿名用戶,則繼續(xù)執(zhí)行;非匿名用戶,拋出“未授權訪問”信息??
  • ????????????????????if?(isAnonymous)??
  • ????????????????????????base.OnActionExecuting(actionContext);??
  • ????????????????????else??
  • ????????????????????????actionContext.Response?=?new?HttpResponseMessage(HttpStatusCode.Unauthorized);??
  • ????????????????}??
  • ????????????????else??
  • ????????????????{??
  • ????????????????????base.OnActionExecuting(actionContext);??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?校驗用戶ticket信息??
  • ????????///?</summary>??
  • ????????///?<param?name="encryptTicket"></param>??
  • ????????///?<returns></returns>??
  • ????????private?bool?ValidateUserTicket(string?encryptTicket)??
  • ????????{??
  • ????????????var?userTicket?=?FormsAuthentication.Decrypt(encryptTicket);??
  • ????????????var?userTicketData?=?userTicket.UserData;??
  • ??
  • ????????????string?userName?=?userTicketData.Substring(0,?userTicketData.IndexOf(":"));??
  • ????????????string?password?=?userTicketData.Substring(userTicketData.IndexOf(":")?+?1);??
  • ??
  • ????????????//檢查用戶名、密碼是否正確,驗證是合法用戶??
  • ????????????//var?isQuilified?=?CheckUser(userName,?password);??
  • ????????????return?true;??
  • ????????}??
  • ????}??
  • [csharp]?view plaincopy
  • ///?<summary>??
  • ????///?基本驗證Attribtue,用以Action的權限處理??
  • ????///?</summary>??
  • ????public?class?BasicAuthenticationAttribute?:?ActionFilterAttribute??
  • ????{??
  • ????????///?<summary>??
  • ????????///?檢查用戶是否有該Action執(zhí)行的操作權限??
  • ????????///?</summary>??
  • ????????///?<param?name="actionContext"></param>??
  • ????????public?override?void?OnActionExecuting(HttpActionContext?actionContext)??
  • ????????{??
  • ????????????//檢驗用戶ticket信息,用戶ticket信息來自調(diào)用發(fā)起方??
  • ????????????if?(actionContext.Request.Headers.Authorization?!=?null)??
  • ????????????{??
  • ????????????????//解密用戶ticket,并校驗用戶名密碼是否匹配??
  • ????????????????var?encryptTicket?=?actionContext.Request.Headers.Authorization.Parameter;??
  • ????????????????if?(ValidateUserTicket(encryptTicket))??
  • ????????????????????base.OnActionExecuting(actionContext);??
  • ????????????????else??
  • ????????????????????actionContext.Response?=?new?HttpResponseMessage(HttpStatusCode.Unauthorized);?????????????????????
  • ????????????}??
  • ????????????else??
  • ????????????{??
  • ????????????????//檢查web.config配置是否要求權限校驗??
  • ????????????????bool?isRquired?=?(WebConfigurationManager.AppSettings["WebApiAuthenticatedFlag"].ToString()?==?"true");??
  • ????????????????if?(isRquired)??
  • ????????????????{??
  • ????????????????????//如果請求Header不包含ticket,則判斷是否是匿名調(diào)用??
  • ????????????????????var?attr?=?actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();??
  • ????????????????????bool?isAnonymous?=?attr.Any(a?=>?a?is?AllowAnonymousAttribute);??
  • ??
  • ????????????????????//是匿名用戶,則繼續(xù)執(zhí)行;非匿名用戶,拋出“未授權訪問”信息??
  • ????????????????????if?(isAnonymous)??
  • ????????????????????????base.OnActionExecuting(actionContext);??
  • ????????????????????else??
  • ????????????????????????actionContext.Response?=?new?HttpResponseMessage(HttpStatusCode.Unauthorized);??
  • ????????????????}??
  • ????????????????else??
  • ????????????????{??
  • ????????????????????base.OnActionExecuting(actionContext);??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ??
  • ????????///?<summary>??
  • ????????///?校驗用戶ticket信息??
  • ????????///?</summary>??
  • ????????///?<param?name="encryptTicket"></param>??
  • ????????///?<returns></returns>??
  • ????????private?bool?ValidateUserTicket(string?encryptTicket)??
  • ????????{??
  • ????????????var?userTicket?=?FormsAuthentication.Decrypt(encryptTicket);??
  • ????????????var?userTicketData?=?userTicket.UserData;??
  • ??
  • ????????????string?userName?=?userTicketData.Substring(0,?userTicketData.IndexOf(":"));??
  • ????????????string?password?=?userTicketData.Substring(userTicketData.IndexOf(":")?+?1);??
  • ??
  • ????????????//檢查用戶名、密碼是否正確,驗證是合法用戶??
  • ????????????//var?isQuilified?=?CheckUser(userName,?password);??
  • ????????????return?true;??
  • ????????}??
  • ????}??
  • ?

    5.3 api服務Controller實例

    [csharp]?view plaincopy
  • public?class?ProductController?:?ApiControllerBase??
  • {??
  • ??
  • ????????[HttpGet]??
  • ????????public?object?Find(string?id)??
  • ????????{??
  • ????????????return?ProductServiceInstance.Find(2);??
  • ????????}??
  • ??
  • ?????//?GET?api/product/5??
  • ????????[HttpGet]??
  • ????????[AllowAnonymous]??
  • ????????public?Product?Get(string?id)??
  • ????????{??
  • ????????????var?headers?=?Request.Headers;??
  • ????????????var?p?=?ProductServiceInstance.GetById<Product,?EPProduct>(long.Parse(id));??
  • ????????????if?(p?==?null)??
  • ????????????{??
  • ??????????????????throw?new?HttpResponseException(new?HttpResponseMessage(HttpStatusCode.BadRequest)??
  • ??????????????????Content?=?new?StringContent("id3?not?found"),?ReasonPhrase?=?"product?id?not?exist."?});??
  • ????????????}??
  • ????????????return?p;??
  • ????????}??
  • }??
  • [csharp]?view plaincopy
  • public?class?ProductController?:?ApiControllerBase??
  • {??
  • ??
  • ????????[HttpGet]??
  • ????????public?object?Find(string?id)??
  • ????????{??
  • ????????????return?ProductServiceInstance.Find(2);??
  • ????????}??
  • ??
  • ?????//?GET?api/product/5??
  • ????????[HttpGet]??
  • ????????[AllowAnonymous]??
  • ????????public?Product?Get(string?id)??
  • ????????{??
  • ????????????var?headers?=?Request.Headers;??
  • ????????????var?p?=?ProductServiceInstance.GetById<Product,?EPProduct>(long.Parse(id));??
  • ????????????if?(p?==?null)??
  • ????????????{??
  • ??????????????????throw?new?HttpResponseException(new?HttpResponseMessage(HttpStatusCode.BadRequest)??
  • ??????????????????Content?=?new?StringContent("id3?not?found"),?ReasonPhrase?=?"product?id?not?exist."?});??
  • ????????????}??
  • ????????????return?p;??
  • ????????}??
  • }??


  • 6. 其它配置說明

    6.1 Mvc前端Web.Config 配置

    [html]?view plaincopy
  • <system.web>??
  • ????<compilation?debug="true"?targetFramework="4.5">??
  • ??????<assemblies>??
  • ????????<add?assembly="System.Web.Http.Data.Helpers,?Version=4.0.0.0,?Culture=neutral,?PublicKeyToken=31bf3856ad364e35"?/>??
  • ??????</assemblies>??
  • ????</compilation>??
  • ????<httpRuntime?targetFramework="4.5"?/>??
  • ????<authentication?mode="Forms">??
  • ??????<forms?loginUrl="~/Account/Login"?defaultUrl="~/Home/Index"?protection="All"?timeout="90"?name=".AuthCookie"></forms>??
  • ????</authentication>??
  • ????<machineKey?validationKey="3FFA12388DDF585BA5D35E7BC87E3F0AB47FBBEBD12240DD3BEA2BEAEC4ABA213F22AD27E8FAD77DCFEE306219691434908D193A17C1FC8DCE51B71A4AE54920"?decryptionKey="ECB6A3AF9ABBF3F16E80685ED68DC74B0B13CCEE538EBBA97D0B893139683B3B"?validation="SHA1"?decryption="AES"?/>??
  • </system.web>??
  • [html]?view plaincopy
  • <system.web>??
  • ????<compilation?debug="true"?targetFramework="4.5">??
  • ??????<assemblies>??
  • ????????<add?assembly="System.Web.Http.Data.Helpers,?Version=4.0.0.0,?Culture=neutral,?PublicKeyToken=31bf3856ad364e35"?/>??
  • ??????</assemblies>??
  • ????</compilation>??
  • ????<httpRuntime?targetFramework="4.5"?/>??
  • ????<authentication?mode="Forms">??
  • ??????<forms?loginUrl="~/Account/Login"?defaultUrl="~/Home/Index"?protection="All"?timeout="90"?name=".AuthCookie"></forms>??
  • ????</authentication>??
  • ????<machineKey?validationKey="3FFA12388DDF585BA5D35E7BC87E3F0AB47FBBEBD12240DD3BEA2BEAEC4ABA213F22AD27E8FAD77DCFEE306219691434908D193A17C1FC8DCE51B71A4AE54920"?decryptionKey="ECB6A3AF9ABBF3F16E80685ED68DC74B0B13CCEE538EBBA97D0B893139683B3B"?validation="SHA1"?decryption="AES"?/>??
  • </system.web>??

  • machineKey節(jié)點配置,是應用于對用戶ticket數(shù)據(jù)加密和解密。

    6.2 WebApi服務端Web.Config配置

    [html]?view plaincopy
  • ?<system.web>??
  • ????<machineKey?validationKey="3FF112388DDF585BA5D35E7BC87E3F0AB47FBBEBD12240DD3BEA2BEAEC4ABA213F22AD27E8FAD77DCFEE306219691434908D193A17C1FC8DCE51B71A4AE54920"?decryptionKey="ECB6A3AF9ABBF3F16E80685ED68DC74B0B13CCEE538EBBA97D0B893139683B3B"?validation="SHA1"?decryption="AES"?/>??
  • </system.web>??
  • [html]?view plaincopy
  • ?<system.web>??
  • ????<machineKey?validationKey="3FF112388DDF585BA5D35E7BC87E3F0AB47FBBEBD12240DD3BEA2BEAEC4ABA213F22AD27E8FAD77DCFEE306219691434908D193A17C1FC8DCE51B71A4AE54920"?decryptionKey="ECB6A3AF9ABBF3F16E80685ED68DC74B0B13CCEE538EBBA97D0B893139683B3B"?validation="SHA1"?decryption="AES"?/>??
  • </system.web>??

  • machineKey節(jié)點配置,是應用于對用戶ticket數(shù)據(jù)加密和解密。

    7. 總結

    Web系統(tǒng)的用戶登錄及頁面操作權限驗證在處理邏輯上比較復雜,需要考慮到Form認證、匿名訪問,Session和Cookie存儲,以及Session和Cookie的過期處理,本文實現(xiàn)了整個權限驗證框架的基本功能,供系統(tǒng)架構設計人員以及Web開發(fā)人員參考。

    轉載于:https://www.cnblogs.com/robinapp/p/4308708.html

    總結

    以上是生活随笔為你收集整理的WebApi权限验证流程的设计和实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。