激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - .net MVC使用IPrincipal進行Form登錄即權限驗證(3)

.net MVC使用IPrincipal進行Form登錄即權限驗證(3)

2020-05-25 13:58清幽火焰 ASP.NET教程

這篇文章主要為大家詳細介紹了.net MVC使用IPrincipal進行Form登錄即權限驗證,具有一定的參考價值,感興趣的小伙伴們可以參考一下

.net MVC使用IPrincipal進行Form登錄即權限驗證,供大家參考,具體內容如下

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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的類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/// <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

?
1
2
3
4
5
protected void Application_PostAuthenticateRequest(object sender, System.EventArgs e)
 {
  HttpContext.Current.User =
  HttpFormsAuthentication.TryParsePrincipal(HttpContext.Current);
 }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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實現登錄邏輯

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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添加特性標簽

?
1
2
3
4
5
6
7
8
9
[FormAuthorize(Roles = "1,2")]
public class HomeController : Controller
{
[FormAuthorize]
public ActionResult Index()
{
 return View();
}
}

如圖

.net MVC使用IPrincipal進行Form登錄即權限驗證(3)

.net MVC使用IPrincipal進行Form登錄即權限驗證(3)

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

?
1
2
3
4
5
6
7
8
9
public class FilterConfig
 {
 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 {
 filters.Add(new HandleErrorAttribute());
 //全局注冊filter
 filters.Add(new FormAuthorizeAttribute());
 }
 }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/pengdylan/p/6407479.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产女同疯狂激烈互摸 | 欧美精品毛片 | 香蕉视频网站在线观看 | 亚洲一区在线视频 | 免费一级a毛片免费观看 | 日本精品黄色 | 欧美成人一区二区视频 | 欧美日本综合 | 国产亚洲精彩视频 | 久久激情国产 | 国产va在线观看免费 | 国产va在线观看 | 美女羞羞视频网站 | 午夜视频在线 | 久久久久久免费 | 黄色片网站免费 | 国产一区二区欧美精品 | 久久美女色视频 | 国产精品久久久久久久久久大牛 | 男男羞羞视频网站国产 | 精品国产乱码一区二区 | 一级黄色免费观看视频 | 国产一级免费电影 | 国产在线一区二区三区 | 草妞视频 | 久久精品国产99久久久古代 | 日韩精品免费一区二区三区 | 国产流白浆高潮在线观看 | 麻豆视频观看 | 毛片免费视频观看 | 毛片一区二区三区四区 | 国产免费人做人爱午夜视频 | 天天夜干| 欧美成年人视频在线观看 | 欧美男人天堂网 | 国产精品999在线观看 | 国产免费一区二区三区最新不卡 | 中国美女一级黄色大片 | 久久久人成影片一区二区三区 | 国产精品一区二区在线 | 国产午夜免费福利 |