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

1.在MVC項(xiàng)目中添加用戶(hù)類(lèi),可以根據(jù)實(shí)際項(xiàng)目需求添加必要屬性
public class UserData
{
/// <summary>
/// ID
/// </summary>
public int UserId { get; set; }
/// <summary>
/// 用戶(hù)名
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 角色I(xiàn)D列表
/// </summary>
public List<int> Roles { get; set; }
}2.添加類(lèi)Principal實(shí)現(xiàn)IPrincipal接口
public class Principal : IPrincipal
{
public IIdentity Identity { get; private set;}
public UserData Account { get; set; }
/// <summary>
/// 構(gòu)造函數(shù)
/// </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接口有對(duì)象Identity已經(jīng)需要實(shí)現(xiàn)驗(yàn)證角色方法IsInRole()。在我們的實(shí)現(xiàn)類(lèi)中添加了"用戶(hù)信息(UserData)"屬性Account。
構(gòu)造函數(shù)中進(jìn)行了初始化,第一個(gè)對(duì)象為Form驗(yàn)證的票據(jù)對(duì)象,下面ticket會(huì)攜帶用戶(hù)信息一起保存進(jìn)cookie中。
3.創(chuàng)建存儲(chǔ)cookie和讀取cookie的類(lèi)
/// <summary>
/// 寫(xiě)入cookie和讀取cookie
/// </summary>
public class HttpFormsAuthentication
{
//將用戶(hù)信息通過(guò)ticket加密保存到cookie
public static void SetAuthenticationCoolie(UserData account, int rememberDay = 0)
{
if (account == null)
throw new ArgumentNullException("account");
//序列化account對(duì)象
string accountJson = JsonConvert.SerializeObject(account);
//創(chuàng)建用戶(hù)票據(jù)
var ticket = new FormsAuthenticationTicket(1, account.UserName, DateTime.Now, DateTime.Now.AddDays(rememberDay), false, accountJson);
//加密
string encryptAccount = FormsAuthentication.Encrypt(ticket);
//創(chuàng)建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);
//寫(xiě)入Cookie
HttpContext.Current.Response.Cookies.Remove(cookie.Name);
HttpContext.Current.Response.Cookies.Add(cookie);
}
//獲取cookie并解析出用戶(hù)信息
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);
}
}存儲(chǔ)cookie時(shí)將用戶(hù)信息序列化后的字符串a(chǎn)ccountJson由ticket其攜帶加密后保存入cookie中,具體的accountJson被賦值給FormsAuthenticationTicket的UserData屬性。
可看到解析時(shí)將ticket.UserData反序列化后得到了原始的用戶(hù)信息對(duì)象,然后生成Principal對(duì)象。
解析cookie得到Principal對(duì)象的方法TryParsePrincipal,下面會(huì)在發(fā)起請(qǐng)求時(shí)用到,而返回的Principal對(duì)象被賦值給HttpContext.User。
4.在Global.asax中注冊(cè)Application_PostAuthenticateRequest事件,保證權(quán)限驗(yàn)證前將cookie中的用戶(hù)信息取出賦值給User
protected void Application_PostAuthenticateRequest(object sender, System.EventArgs e)
{
HttpContext.Current.User =
HttpFormsAuthentication.TryParsePrincipal(HttpContext.Current);
}5.集成AuthorizeAttribute特性類(lèi)并重寫(xiě)AuthorizeCore,HandleUnauthorizedRequest方法
public class FormAuthorizeAttribute : AuthorizeAttribute
{
/// <summary>
/// 先進(jìn)入此方法,此方法中會(huì)調(diào)用 AuthorizeCore 驗(yàn)證邏輯,驗(yàn)證不通過(guò)會(huì)調(diào)用 HandleUnauthorizedRequest 方法
/// </summary>
/// <param name="filterContext"></param>
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
}
/// <summary>
/// 權(quán)限驗(yàn)證
/// </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)
{
//驗(yàn)證不通過(guò),直接跳轉(zhuǎn)到相應(yīng)頁(yè)面,注意:如果不是喲娜那個(gè)以下跳轉(zhuǎn),則會(huì)繼續(xù)執(zhí)行Action方法
filterContext.Result = new RedirectResult("~/Login/Index");
}
}AuthorizeCore與HandleUnauthorizedRequest方法均是在方法OnAuthorization中調(diào)用,AuthorizeCore驗(yàn)證不通過(guò)才會(huì)調(diào)用HandleUnauthorizedRequest方法。
將驗(yàn)證代碼在AuthorizeCore中實(shí)現(xiàn),驗(yàn)證不通過(guò)的邏輯在HandleUnauthorizedRequest方法中實(shí)現(xiàn)。
6.添加LoginController實(shí)現(xiàn)登錄邏輯
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.對(duì)需要驗(yàn)證的controller或action添加特性標(biāo)簽
[FormAuthorize(Roles = "1,2")]
public class HomeController : Controller
{
[FormAuthorize]
public ActionResult Index()
{
return View();
}
}如圖


8.在添加FilterConfig中添加全局注冊(cè)filter,減少每個(gè)action分別設(shè)置。如果有不需要驗(yàn)證的頁(yè)面,添加[AllowAnonymous]特性即可
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
//全局注冊(cè)filter
filters.Add(new FormAuthorizeAttribute());
}
}以上是“.net MVC如何使用IPrincipal進(jìn)行Form登錄即權(quán)限驗(yàn)證”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
文章名稱(chēng):.netMVC如何使用IPrincipal進(jìn)行Form登錄即權(quán)限驗(yàn)證-創(chuàng)新互聯(lián)
文章URL:http://chinadenli.net/article2/hjiic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、網(wǎng)站營(yíng)銷(xiāo)、定制網(wǎng)站、關(guān)鍵詞優(yōu)化、響應(yīng)式網(wǎng)站、網(wǎng)站設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容