Asp.net Mvc 身份驗證、異常處理、權限驗證(攔截器)


本問主要介紹asp.net的身份驗證機制及asp.net MVC攔截器在項目中的運用。現在讓我們來模擬一個簡單的流程:用戶登錄》權限驗證》異常處理。

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);//序列化用戶實體

//保存身份信息,參數說明可以看提示
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);

現在身份信息就保存到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執行之前會先運行攔截器中的代碼。這里同時可以身份驗證是否過期。

    /// <summary>
    /// 權限驗證
    /// </summary>
    public class AuthAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 角色名稱
        /// </summary>
        public string Code { get; set; }

        /// <summary>
        /// 驗證權限(action執行前會先執行這里)
        /// </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")]//驗證通過,發生異常
        public ActionResult Index3()
        {
            return View();
        }
    }

這樣就可以把權限控制到action了。

3、異常處理

上面HomeController並不是繼承Controller,而是繼承我們自己定義的一個BaseController,那么我們來看看BaseController中有寫什么東西?

    [ErrorAttribute]
    public class BaseController : Controller
    {
        //所有Controller都繼承BaseController,則都會進行異常捕獲
    }

在這里BaseController只做了一件事情,就是增加了一個ErrorAttribute的錯誤攔截器,那么只要是在Controller中發生的異常都會在ErrorAttribute中進行處理,你可以記錄到數據庫等操作。那么我們看看ErrorAttribute是怎么工作的。

    /// <summary>
    /// 錯誤日志(Controller發生異常時會執行這里)
    /// </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;//錯誤發生地址

            filterContext.ExceptionHandled = true;
            filterContext.Result = new RedirectResult("/Error/Show/");//跳轉至錯誤提示頁面
        }
    }

在這里可以把異常捕獲,然后跳轉到友好的錯誤提示頁面。在MVC中幾個操作就可以這樣簡單的完成了,關於代碼在文章下面會提供下載。

 

  實例代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM