Mvc 身份验证、异常处理、权限验证

1、用户登录 
验证用户是否登录成功步骤直接忽略,用户登录成功后怎么保存当前用户登录信息(session,cookie),本文介绍的是身份验证(其实就是基于cookie)的,下面看看代码。 
引入命名空间 
using System.Web.Security; 

1 Users ModelUser = new Users() { ID = 10000, Name = UserName, UserName = UserName, PassWord = PassWord, Roles = "admin" };//用户实体 
2 string UserData = SerializeHelper.Instance.JsonSerialize<Users>(ModelUser);//序列化用户实体 
3 //保存身份信息,参数说明可以看提示 
4 FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(1, UserName, DateTime.Now, DateTime.Now.AddHours(12), false, UserData); 
5 HttpCookie Cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(Ticket));//加密身份信息,保存至Cookie 
6 Response.Cookies.Add(Cookie); 
View Code

现在身份信息就保存到cookie中了,如果有场景需要用到当前用户的用户ID或者别的信息的时候该怎么办呢? 

那么,我们重新在cookie中获取身份信息,然后解密,再反序列化成用户实体就OK了。

 1 /// <summary> 
 2 /// 获取用户登录信息 
 3 /// </summary> 
 4 /// <returns></returns> 
 5 public Users GetUser() 
 6 { 
 7 if (HttpContext.Current.Request.IsAuthenticated)//是否通过身份验证 
 8 { 
 9 HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];//获取cookie 
10 FormsAuthenticationTicket Ticket = FormsAuthentication.Decrypt(authCookie.Value);//解密 
11 return SerializeHelper.Instance.JsonDeserialize<Users>(Ticket.UserData);//反序列化 
12 } 
13 return null; 
14 }
View Code

2、权限验证 
这里用到的是MVC中的action拦截器(重写OnActionExecuting),在action执行之前会先运行拦截器中的代码。这里同时可以身份验证是否过期。 

 1 // <summary> 
 2 /// 权限验证 
 3 /// </summary> 
 4 public class AuthAttribute : ActionFilterAttribute 
 5 { 
 6 /// <summary> 
 7 /// 角色名称 
 8 /// </summary> 
 9 public string Code { get; set; } 
10 /// <summary> 
11 /// 验证权限(action执行前会先执行这里) 
12 /// </summary> 
13 /// <param name="filterContext"></param> 
14 public override void OnActionExecuting(ActionExecutingContext filterContext) 
15 { 
16 //如果存在身份信息 
17 if (!HttpContext.Current.User.Identity.IsAuthenticated) 
18 { 
19 ContentResult Content = new ContentResult(); 
20 Content.Content = string.Format("<script type='text/javascript'>alert('请先登录!');window.location.href='{0}';</script>", FormsAuthentication.LoginUrl); 
21 filterContext.Result = Content; 
22 } 
23 else 
24 { 
25 string[] Role = CheckLogin.Instance.GetUser().Roles.Split(',');//获取所有角色 
26 if (!Role.Contains(Code))//验证权限 
27 { 
28 //验证不通过 
29 ContentResult Content = new ContentResult(); 
30 Content.Content = "<script type='text/javascript'>alert('权限验证不通过!');history.go(-1);</script>"; 
31 filterContext.Result = Content; 
32 } 
33 } 
34 } 
35 } 
View Code

那么在action中怎么去调用呢?这里贴出HomeController中的代码来看下。 

 1 public class HomeController : BaseController 
 2 { 
 3 [AuthAttribute(Code = "admin")]//验证通过(这个action只允许admin查看) 
 4 public ActionResult Index() 
 5 { 
 6 Users ModelUser = CheckLogin.Instance.GetUser(); 
 7 return View(ModelUser); 
 8 } 
 9 [AuthAttribute(Code = "user")]//验证不通过 
10 public ActionResult Index2() 
11 { 
12 return View(); 
13 } 
14 [AuthAttribute(Code = "admin")]//验证通过,发生异常 
15 public ActionResult Index3() 
16 { 
17 return View(); 
18 } 
19 } 
View Code

这样就可以把权限控制到action了。 
3、异常处理 
上面HomeController并不是继承Controller,而是继承我们自己定义的一个BaseController,那么我们来看看BaseController中有写什么东西? 

1 [ErrorAttribute] 
2 public class BaseController : Controller 
3 { 
4 //所有Controller都继承BaseController,则都会进行异常捕获 
5 }
View Code

在这里BaseController只做了一件事情,就是增加了一个ErrorAttribute的错误拦截器,那么只要是在Controller中发生的异常都会在ErrorAttribute中进行处理,你可以记录到数据库等操作。那么我们看看ErrorAttribute是怎么工作的。

 1 /// <summary> 
 2 /// 错误日志(Controller发生异常时会执行这里) 
 3 /// </summary> 
 4 public class ErrorAttribute : ActionFilterAttribute, IExceptionFilter 
 5 { 
 6 /// <summary> 
 7 /// 异常 
 8 /// </summary> 
 9 /// <param name="filterContext"></param> 
10 public void OnException(ExceptionContext filterContext) 
11 { 
12 //获取异常信息,入库保存 
13 Exception Error = filterContext.Exception; 
14 string Message = Error.Message;//错误信息 
15 string Url = HttpContext.Current.Request.RawUrl;//错误发生地址 
16 filterContext.ExceptionHandled = true; 
17 filterContext.Result = new RedirectResult("/Error/Show/");//跳转至错误提示页面 
18 } 
19 } 
View Code

在这里可以把异常捕获,然后跳转到友好的错误提示页面。在MVC中几个操作就可以这样简单的完成了,关于代码在文章下面会提供下载。 

实例代码 

  

posted @ 2013-06-14 14:38  山村色野先生  阅读(312)  评论(0)    收藏  举报