Asp.net Mvc 身份驗證、異常處理、權限驗證(攔截器)實現(xiàn)代碼
更新時間:2012年10月27日 10:07:59 作者:
本問主要介紹asp.net的身份驗證機制及asp.net MVC攔截器在項目中的運用。現(xiàn)在讓我們來模擬一個簡單的流程:用戶登錄》權限驗證》異常處理
1、用戶登錄
驗證用戶是否登錄成功步驟直接忽略,用戶登錄成功后怎么保存當前用戶登錄信息(session,cookie),本文介紹的是身份驗證(其實就是基于cookie)的,下面看看代碼。
引入命名空間
using System.Web.Security;
Users ModelUser = new Users() { ID = 10000, Name = UserName, UserName = UserName, PassWord = PassWord, Roles = "admin" };//用戶實體
string UserData = SerializeHelper.Instance.JsonSerialize<Users>(ModelUser);//序列化用戶實體
//保存身份信息,參數(shù)說明可以看提示
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(1, UserName, DateTime.Now, DateTime.Now.AddHours(12), false, UserData);
HttpCookie Cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(Ticket));//加密身份信息,保存至Cookie
Response.Cookies.Add(Cookie);
現(xiàn)在身份信息就保存到cookie中了,如果有場景需要用到當前用戶的用戶ID或者別的信息的時候該怎么辦呢?
那么,我們重新在cookie中獲取身份信息,然后解密,再反序列化成用戶實體就OK了。
/// <summary>
/// 獲取用戶登錄信息
/// </summary>
/// <returns></returns>
public Users GetUser()
{
if (HttpContext.Current.Request.IsAuthenticated)//是否通過身份驗證
{
HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];//獲取cookie
FormsAuthenticationTicket Ticket = FormsAuthentication.Decrypt(authCookie.Value);//解密
return SerializeHelper.Instance.JsonDeserialize<Users>(Ticket.UserData);//反序列化
}
return null;
}
2、權限驗證
這里用到的是MVC中的action攔截器(重寫OnActionExecuting),在action執(zhí)行之前會先運行攔截器中的代碼。這里同時可以身份驗證是否過期。
/// <summary>
/// 權限驗證
/// </summary>
public class AuthAttribute : ActionFilterAttribute
{
/// <summary>
/// 角色名稱
/// </summary>
public string Code { get; set; }
/// <summary>
/// 驗證權限(action執(zhí)行前會先執(zhí)行這里)
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//如果存在身份信息
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
ContentResult Content = new ContentResult();
Content.Content = string.Format("<script type='text/javascript'>alert('請先登錄!');window.location.href='{0}';</script>", FormsAuthentication.LoginUrl);
filterContext.Result = Content;
}
else
{
string[] Role = CheckLogin.Instance.GetUser().Roles.Split(',');//獲取所有角色
if (!Role.Contains(Code))//驗證權限
{
//驗證不通過
ContentResult Content = new ContentResult();
Content.Content = "<script type='text/javascript'>alert('權限驗證不通過!');history.go(-1);</script>";
filterContext.Result = Content;
}
}
}
}
那么在action中怎么去調用呢?這里貼出HomeController中的代碼來看下。
public class HomeController : BaseController
{
[AuthAttribute(Code = "admin")]//驗證通過(這個action只允許admin查看)
public ActionResult Index()
{
Users ModelUser = CheckLogin.Instance.GetUser();
return View(ModelUser);
}
[AuthAttribute(Code = "user")]//驗證不通過
public ActionResult Index2()
{
return View();
}
[AuthAttribute(Code = "admin")]//驗證通過,發(fā)生異常
public ActionResult Index3()
{
return View();
}
}
這樣就可以把權限控制到action了。
3、異常處理
上面HomeController并不是繼承Controller,而是繼承我們自己定義的一個BaseController,那么我們來看看BaseController中有寫什么東西?
[ErrorAttribute]
public class BaseController : Controller
{
//所有Controller都繼承BaseController,則都會進行異常捕獲
}
在這里BaseController只做了一件事情,就是增加了一個ErrorAttribute的錯誤攔截器,那么只要是在Controller中發(fā)生的異常都會在ErrorAttribute中進行處理,你可以記錄到數(shù)據(jù)庫等操作。那么我們看看ErrorAttribute是怎么工作的。
/// <summary>
/// 錯誤日志(Controller發(fā)生異常時會執(zhí)行這里)
/// </summary>
public class ErrorAttribute : ActionFilterAttribute, IExceptionFilter
{
/// <summary>
/// 異常
/// </summary>
/// <param name="filterContext"></param>
public void OnException(ExceptionContext filterContext)
{
//獲取異常信息,入庫保存
Exception Error = filterContext.Exception;
string Message = Error.Message;//錯誤信息
string Url = HttpContext.Current.Request.RawUrl;//錯誤發(fā)生地址
filterContext.ExceptionHandled = true;
filterContext.Result = new RedirectResult("/Error/Show/");//跳轉至錯誤提示頁面
}
}
在這里可以把異常捕獲,然后跳轉到友好的錯誤提示頁面。在MVC中幾個操作就可以這樣簡單的完成了,關于代碼在文章下面會提供下載。
實例代碼
作者:LyIng.Net
驗證用戶是否登錄成功步驟直接忽略,用戶登錄成功后怎么保存當前用戶登錄信息(session,cookie),本文介紹的是身份驗證(其實就是基于cookie)的,下面看看代碼。
引入命名空間
using System.Web.Security;
復制代碼 代碼如下:
Users ModelUser = new Users() { ID = 10000, Name = UserName, UserName = UserName, PassWord = PassWord, Roles = "admin" };//用戶實體
string UserData = SerializeHelper.Instance.JsonSerialize<Users>(ModelUser);//序列化用戶實體
//保存身份信息,參數(shù)說明可以看提示
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(1, UserName, DateTime.Now, DateTime.Now.AddHours(12), false, UserData);
HttpCookie Cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(Ticket));//加密身份信息,保存至Cookie
Response.Cookies.Add(Cookie);
現(xiàn)在身份信息就保存到cookie中了,如果有場景需要用到當前用戶的用戶ID或者別的信息的時候該怎么辦呢?
那么,我們重新在cookie中獲取身份信息,然后解密,再反序列化成用戶實體就OK了。
復制代碼 代碼如下:
/// <summary>
/// 獲取用戶登錄信息
/// </summary>
/// <returns></returns>
public Users GetUser()
{
if (HttpContext.Current.Request.IsAuthenticated)//是否通過身份驗證
{
HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];//獲取cookie
FormsAuthenticationTicket Ticket = FormsAuthentication.Decrypt(authCookie.Value);//解密
return SerializeHelper.Instance.JsonDeserialize<Users>(Ticket.UserData);//反序列化
}
return null;
}
2、權限驗證
這里用到的是MVC中的action攔截器(重寫OnActionExecuting),在action執(zhí)行之前會先運行攔截器中的代碼。這里同時可以身份驗證是否過期。
復制代碼 代碼如下:
/// <summary>
/// 權限驗證
/// </summary>
public class AuthAttribute : ActionFilterAttribute
{
/// <summary>
/// 角色名稱
/// </summary>
public string Code { get; set; }
/// <summary>
/// 驗證權限(action執(zhí)行前會先執(zhí)行這里)
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//如果存在身份信息
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
ContentResult Content = new ContentResult();
Content.Content = string.Format("<script type='text/javascript'>alert('請先登錄!');window.location.href='{0}';</script>", FormsAuthentication.LoginUrl);
filterContext.Result = Content;
}
else
{
string[] Role = CheckLogin.Instance.GetUser().Roles.Split(',');//獲取所有角色
if (!Role.Contains(Code))//驗證權限
{
//驗證不通過
ContentResult Content = new ContentResult();
Content.Content = "<script type='text/javascript'>alert('權限驗證不通過!');history.go(-1);</script>";
filterContext.Result = Content;
}
}
}
}
那么在action中怎么去調用呢?這里貼出HomeController中的代碼來看下。
復制代碼 代碼如下:
public class HomeController : BaseController
{
[AuthAttribute(Code = "admin")]//驗證通過(這個action只允許admin查看)
public ActionResult Index()
{
Users ModelUser = CheckLogin.Instance.GetUser();
return View(ModelUser);
}
[AuthAttribute(Code = "user")]//驗證不通過
public ActionResult Index2()
{
return View();
}
[AuthAttribute(Code = "admin")]//驗證通過,發(fā)生異常
public ActionResult Index3()
{
return View();
}
}
這樣就可以把權限控制到action了。
3、異常處理
上面HomeController并不是繼承Controller,而是繼承我們自己定義的一個BaseController,那么我們來看看BaseController中有寫什么東西?
復制代碼 代碼如下:
[ErrorAttribute]
public class BaseController : Controller
{
//所有Controller都繼承BaseController,則都會進行異常捕獲
}
在這里BaseController只做了一件事情,就是增加了一個ErrorAttribute的錯誤攔截器,那么只要是在Controller中發(fā)生的異常都會在ErrorAttribute中進行處理,你可以記錄到數(shù)據(jù)庫等操作。那么我們看看ErrorAttribute是怎么工作的。
復制代碼 代碼如下:
/// <summary>
/// 錯誤日志(Controller發(fā)生異常時會執(zhí)行這里)
/// </summary>
public class ErrorAttribute : ActionFilterAttribute, IExceptionFilter
{
/// <summary>
/// 異常
/// </summary>
/// <param name="filterContext"></param>
public void OnException(ExceptionContext filterContext)
{
//獲取異常信息,入庫保存
Exception Error = filterContext.Exception;
string Message = Error.Message;//錯誤信息
string Url = HttpContext.Current.Request.RawUrl;//錯誤發(fā)生地址
filterContext.ExceptionHandled = true;
filterContext.Result = new RedirectResult("/Error/Show/");//跳轉至錯誤提示頁面
}
}
在這里可以把異常捕獲,然后跳轉到友好的錯誤提示頁面。在MVC中幾個操作就可以這樣簡單的完成了,關于代碼在文章下面會提供下載。
實例代碼
作者:LyIng.Net
相關文章
asp.net連接數(shù)據(jù)庫 增加,修改,刪除,查詢代碼
asp.net連接數(shù)據(jù)庫,實現(xiàn)增加,修改,刪除,查詢的四大功能完整代碼。2009-07-07ASP.NET輸出PNG圖片時出現(xiàn)GDI+一般性錯誤的解決方法
偶原來的用ASP.NET生成驗證碼圖片時用的是JPG格式,今天想把它改成PNG格式的,結果就出現(xiàn)GDI+一般性錯誤,查了N久資料,才發(fā)現(xiàn)解決的辦法,對分享此解決辦法的網(wǎng)友深表感謝2009-01-01使用最小?WEB?API?實現(xiàn)文件上傳會遇到的坑
這篇文章主要介紹分享使用最小?WEB?API?實現(xiàn)文件上傳時會遇到的坑,在使用?.NET?6?的最小?WEB?API?來實現(xiàn)相同功能時,總是會意外地遇到了不少坑,下面我們就來看看這些坑都是怎么處理的吧,需要的朋友可以參考下2022-02-02- 就是有時候窗口不能夠成功置頂,這時需要重新切換下標簽,就可以置頂了,本文介紹C# SetWindowPos實現(xiàn)窗口置頂?shù)姆椒?/div> 2012-12-12
asp.net 中將表單提交到另一頁 Code-Behind(代碼和html在不同的頁面)
To send Server control values from a different Web Forms page2009-04-04最新評論