中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

.net MVC如何使用IPrincipal進行Form登錄即權限驗證

發布時間:2021-08-09 10:26:42 來源:億速云 閱讀:137 作者:小新 欄目:開發技術

這篇文章主要介紹.net MVC如何使用IPrincipal進行Form登錄即權限驗證,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

1.在MVC項目中添加用戶類,可以根據實際項目需求添加必要屬性

public class UserData
 {
 /// <summary>
 /// ID
 /// </summary>
 public int UserId { get; set; }

 /// <summary>
 /// 用戶名
 /// </summary>
 public string UserName { get; set; }

 /// <summary>
 /// 角色ID列表
 /// </summary>
 public List<int> Roles { get; set; }
 }

2.添加類Principal實現IPrincipal接口

public class Principal : IPrincipal
 {
 public IIdentity Identity { get; private set;}

 public UserData Account { get; set; }

 /// <summary>
 /// 構造函數
 /// </summary>
 /// <param name="ticket"></param>
 /// <param name="account"></param>
 public Principal(FormsAuthenticationTicket ticket, UserData account)
 {
  if (ticket == null)
  throw new ArgumentNullException("ticket");
  if (account == null)
  throw new ArgumentNullException("UserData");

  this.Identity = new FormsIdentity(ticket);
  this.Account = account;
 }

 public bool IsInRole(string role)
 {
  if (string.IsNullOrEmpty(role))
  return true;
  if (this.Account == null || this.Account.Roles == null)
  return false;
  return role.Split(',').Any(q => Account.Roles.Contains(int.Parse(q)));
 }
 }

IPrincipal接口有對象Identity已經需要實現驗證角色方法IsInRole()。在我們的實現類中添加了"用戶信息(UserData)"屬性Account。

構造函數中進行了初始化,第一個對象為Form驗證的票據對象,下面ticket會攜帶用戶信息一起保存進cookie中。

3.創建存儲cookie和讀取cookie的類

/// <summary>
 /// 寫入cookie和讀取cookie
 /// </summary>
 public class HttpFormsAuthentication
 {
 //將用戶信息通過ticket加密保存到cookie
 public static void SetAuthenticationCoolie(UserData account, int rememberDay = 0)
 {
  if (account == null)
  throw new ArgumentNullException("account");

  //序列化account對象
  string accountJson = JsonConvert.SerializeObject(account);
  //創建用戶票據
  var ticket = new FormsAuthenticationTicket(1, account.UserName, DateTime.Now, DateTime.Now.AddDays(rememberDay), false, accountJson);
  //加密
  string encryptAccount = FormsAuthentication.Encrypt(ticket);

  //創建cookie
  var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptAccount)
  {
  HttpOnly = true,
  Secure = FormsAuthentication.RequireSSL,
  Domain = FormsAuthentication.CookieDomain,
  Path = FormsAuthentication.FormsCookiePath
  };

  if (rememberDay > 0)
  cookie.Expires = DateTime.Now.AddDays(rememberDay);

  //寫入Cookie
  HttpContext.Current.Response.Cookies.Remove(cookie.Name);
  HttpContext.Current.Response.Cookies.Add(cookie);
 }

 //獲取cookie并解析出用戶信息
 public static Principal TryParsePrincipal(HttpContext context)
 {
  if (context == null)
  throw new ArgumentNullException("context");
  HttpRequest request = context.Request;
  HttpCookie cookie = request.Cookies[FormsAuthentication.FormsCookieName];
  if (cookie == null || string.IsNullOrEmpty(cookie.Value))
  {
  return null;
  }
  //解密coolie值
  FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

  UserData account = JsonConvert.DeserializeObject<UserData>(ticket.UserData);
  return new Principal(ticket, account);
 }

 }

存儲cookie時將用戶信息序列化后的字符串accountJson由ticket其攜帶加密后保存入cookie中,具體的accountJson被賦值給FormsAuthenticationTicket的UserData屬性。

可看到解析時將ticket.UserData反序列化后得到了原始的用戶信息對象,然后生成Principal對象。

解析cookie得到Principal對象的方法TryParsePrincipal,下面會在發起請求時用到,而返回的Principal對象被賦值給HttpContext.User。

4.在Global.asax中注冊Application_PostAuthenticateRequest事件,保證權限驗證前將cookie中的用戶信息取出賦值給User

protected void Application_PostAuthenticateRequest(object sender, System.EventArgs e)
 {
  HttpContext.Current.User =
  HttpFormsAuthentication.TryParsePrincipal(HttpContext.Current);
 }

 5.集成AuthorizeAttribute特性類并重寫AuthorizeCore,HandleUnauthorizedRequest方法

public class FormAuthorizeAttribute : AuthorizeAttribute
 {
 /// <summary>
 /// 先進入此方法,此方法中會調用 AuthorizeCore 驗證邏輯,驗證不通過會調用 HandleUnauthorizedRequest 方法
 /// </summary>
 /// <param name="filterContext"></param>
 public override void OnAuthorization(AuthorizationContext filterContext)
 {
  base.OnAuthorization(filterContext);
 }

 /// <summary>
 /// 權限驗證
 /// </summary>
 /// <param name="httpContext"></param>
 /// <returns></returns>
 protected override bool AuthorizeCore(HttpContextBase httpContext)
 {
  var user = httpContext.User as Principal;
  if (user != null)
  return user.IsInRole(base.Roles);
  return false;
 }

 protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
 {
  //驗證不通過,直接跳轉到相應頁面,注意:如果不是喲娜那個以下跳轉,則會繼續執行Action方法
  filterContext.Result = new RedirectResult("~/Login/Index");
 }
 }

AuthorizeCore與HandleUnauthorizedRequest方法均是在方法OnAuthorization中調用,AuthorizeCore驗證不通過才會調用HandleUnauthorizedRequest方法。

將驗證代碼在AuthorizeCore中實現,驗證不通過的邏輯在HandleUnauthorizedRequest方法中實現。

6.添加LoginController實現登錄邏輯

namespace MVCAuthorizeTest.Controllers
{
 public class LoginController : Controller
 {
 [AllowAnonymous]
 // GET: Login
 public ActionResult Index(string returnUrl)
 {
  ViewBag.ReturnUrl = returnUrl;
  return View();
 }

 [HttpPost]
 [AllowAnonymous]
 public ActionResult Index(string name, string password, bool rememberMe, string returnUrl)
 {
  var account = new UserData()
  {
  UserName = name,
  UserId = 110,
  Roles = new List<int>() { 1, 2, 3 }
  };
  HttpFormsAuthentication.SetAuthenticationCoolie(account, rememberMe ? 7 : 0);
  if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
  {
  return Redirect(returnUrl);
  }
  else
  {
  return RedirectToAction("Index", "Home");
  }
 }

 // POST: /Account/LogOff
 [HttpPost]
 public ActionResult LogOff()
 {
  System.Web.Security.FormsAuthentication.SignOut();
  return RedirectToAction("Index", "Home");
 }
 }
}

7.對需要驗證的controller或action添加特性標簽

 [FormAuthorize(Roles = "1,2")]
 public class HomeController : Controller
 {
 [FormAuthorize]
 public ActionResult Index()
 {
  return View();
 }
 }

如圖

.net MVC如何使用IPrincipal進行Form登錄即權限驗證.net MVC如何使用IPrincipal進行Form登錄即權限驗證

8.在添加FilterConfig中添加全局注冊filter,減少每個action分別設置。如果有不需要驗證的頁面,添加[AllowAnonymous]特性即可

public class FilterConfig
 {
 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 {
 filters.Add(new HandleErrorAttribute());
 //全局注冊filter
 filters.Add(new FormAuthorizeAttribute());
 }
 }

以上是“.net MVC如何使用IPrincipal進行Form登錄即權限驗證”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

mvc
AI

绥中县| 济阳县| 瑞金市| 广平县| 安丘市| 平安县| 昌宁县| 尉氏县| 临江市| 佛学| 叙永县| 修水县| 离岛区| 莒南县| 剑河县| 叶城县| 东阳市| 龙泉市| 霍邱县| 无棣县| 鄂托克旗| 灵武市| 榆树市| 泌阳县| 桂东县| 潍坊市| 诸暨市| 文安县| 延川县| 汝南县| 淮北市| 嫩江县| 英超| 自治县| 章丘市| 长宁区| 张家口市| 遂宁市| 张北县| 渝中区| 安新县|