在项目开发中,通常我们都会涉及到用户登录才能访问的网页,比如购物网站,我们浏览商品,添加购物车(以前开发的时候在这里就需要登录用户,但是现在有了缓存的实现,这里可以将商品加入缓存,等到结账的时候再登录),选择结账的时候需要登录,那么这时候我们需要跳转到登录页面登录,登录之后还可以回到记录下来的原始的页面,那么这之后我们有好几种方法可以实现这种效果,下面笔者举例两种:
第一种:登录模块不管怎么样都是统一的,就是在每个需要登录的方法里面判断用户是否登录,如果没有登录,则跳转登录,这种的缺点是工作量大,代码冗余。
第二种:使用MVC的特性,定义类继承IAuthorizationFilter,重写OnAuthorization方法即可实现。此方法工作量少,代码不冗余,如果需要登录我们只需要给Controller或者Action给上标签即可。
上面列举了权限认证的两种形式,在实际开发中使用OnAuthorization和特性相结合的情况比较多,在任何能够使用特性的判断中都可以按照下面的思路来实现,例如(登录判断,权限判断,请求判断,去除空格,读取返回路径)等等。
接下来是笔者使用OnAuthorization的一个案例:
BaseController.cs
namespace MvcApplication1.Controllers{ ???public class BaseController : Controller ???{ ???????protected override void OnAuthorization(AuthorizationContext context) ???????{ ???????????//解析控制器的名称 ???????????string ControllerName = context.ActionDescriptor.ControllerDescriptor.ControllerName; ???????????if (ControllerName.ToLower() == "Manager".ToLower())//这里只对Manager的控制器进行权限验证 ???????????{ ???????????????var b = context.HttpContext.Request.Browser;//浏览器判断 ie8 居然是7.0 ???????????????if (b.Browser == "IE" && float.Parse(b.Version) < 7) ???????????????{ ???????????????????context.Result = Content("ie浏览器就只支持ie8+", "text/json"); ???????????????????return; ???????????????} ???????????????//解析出对应的方法 ???????????????var Method = context.Controller.GetType().GetMethods().Where(c => c.Name.ToLower() == context.ActionDescriptor.ActionName.ToLower()).FirstOrDefault(); ???????????????if (Method == null) ???????????????{ ???????????????????context.Result = Content("权限不够", "text/json"); ???????????????????return; ???????????????} ???????????????//解析出方法上面对应的特性 ???????????????AccessAttribute acc = Method.GetCustomAttributes(typeof(AccessAttribute), true).FirstOrDefault() as AccessAttribute; ???????????????if (acc != null) ???????????????{ ???????????????????if (acc.IsAccess == AccessEnum.Login)//需要登录权限 ???????????????????{ ???????????????????????if (!IsLogin()) ???????????????????????{ ???????????????????????????context.HttpContext.Response.Redirect("~/Manager/Login");//如果没有登录,就跳转到登录页面 ???????????????????????????return; ???????????????????????} ???????????????????} ???????????????????else if (acc.IsAccess == AccessEnum.Access)//需要其他权限 ???????????????????{ ???????????????????????if (!IsAccess(context)) ???????????????????????{ ???????????????????????????context.Result = Content("权限不够", "text/json"); ???????????????????????????return; ???????????????????????} ???????????????????} ???????????????} ???????????} ???????????base.OnAuthorization(context); ???????} ???????/// <summary> ???????/// 检查是否登录 ???????/// </summary> ???????/// <returns>一个bool类型的数据,表示用户是否登录</returns> ???????public bool IsLogin() ???????{ ???????????String userName = (String)System.Web.HttpContext.Current.Session["UserName"]; ???????????String Password = (String)System.Web.HttpContext.Current.Session["Password"]; ???????????if (System.Web.HttpContext.Current.Session["UserName"] != null) ???????????{ ???????????????if ("abc".Equals(userName) && "123".Equals(Password)) { ???????????????????return true; ???????????????} ???????????} ???????????else ???????????{ ???????????????//检查Cookies ????????????????HttpCookie cookie_UserName=System.Web.HttpContext.Current.Request.Cookies.Get("UserName"); ????????????????HttpCookie cookie_Password = System.Web.HttpContext.Current.Request.Cookies.Get("Password"); ???????????????//检查用户名和密码 ????????????????if (cookie_UserName == null || cookie_Password == null) ????????????????{ ????????????????????return false; ????????????????} ????????????????else { ????????????????????String user= cookie_UserName.Value; ????????????????????String pass = cookie_Password.Value; ????????????????????//在数据库中检查 ????????????????????if ("abc".Equals(user) && "123".Equals(pass)) { ????????????????????????return true; ????????????????????} ????????????????} ???????????} ???????????return false; ???????} ???????/// <summary> ???????/// 权限检查 ???????/// </summary> ???????/// <param name="context"></param> ???????/// <returns>一个bool的数据,表示用户是否拥有其他权限</returns> ???????public bool IsAccess(AuthorizationContext context) ???????{ ???????????bool isAccess = false; ???????????var controller = context.RouteData.Values.Keys.First(p => p == "controller"); ???????????var action = context.RouteData.Values.Keys.First(p => p == "action"); ???????????var url = "/" + context.RouteData.Values[controller] + "/" + context.RouteData.Values[action]; ???????????//根据controller和action 可以判断权限了 ???????????//isAccess = true; ???????????return isAccess; ???????} ???}}
这里的BaseController类继承了Controller,并且重写了其中了OnAuthorization方法,在OnAuthorization方法中,首先解析出用户请求的Controller名称,然后判断是否需要验证这个Controller,案例中验证的是名为Manager的Controller,得到了对应的Controller后,接下来解析用户请求的具体是什么方法,再利用反射找出方法有什么特性,根据特性进行权限验证。
ManagerController.cs
namespace MvcApplication1.Controllers{ ???public class ManagerController : BaseController ???{ ???????[Access(IsAccess = AccessEnum.Login)] ???????public ActionResult Index() ???????{ ???????????return View("index"); ???????} ???????[Access(IsAccess = AccessEnum.Anonymous)] ???????public ActionResult ToLogin(){ ???????????String user = Request["UserName"]; ???????????String password = Request["Password"]; ???????????if ("abc".Equals(user) && "123".Equals(password)) { ???????????????Session.Add("UserName", "abc"); ???????????????Session.Add("Password", "123"); ???????????????return Index(); ???????????} ???????????return View("Error"); ???????} ???????[Access(IsAccess = AccessEnum.Anonymous)] ???????public ActionResult Login() ???????{ ???????????return View(); ???????} ???}}
AccessAttribute.cs
namespace MvcApplication1.Models.Attribute{ ???/// <summary> ???/// <para>创建自定义权限认证特性</para> ???/// <para>该特性应用的范围可以为类、构造方法、字段、方法、属性</para> ???/// </summary> ???[AttributeUsage(AttributeTargets.Class | ????AttributeTargets.Constructor | ????AttributeTargets.Field | ????AttributeTargets.Method | ????AttributeTargets.Property, ????AllowMultiple = true)] ???public class AccessAttribute : System.Attribute ???{ ???????public AccessEnum IsAccess { set; get; } ???} ???/// <summary> ???/// 权限认证级别 ???/// </summary> ???public enum AccessEnum ???{ ???????/// <summary> ???????/// 权限认证 ???????/// </summary> ???????Access, ???????/// <summary> ???????/// 只需要登录 ???????/// </summary> ???????Login, ???????/// <summary> ???????/// 不需要登录 ???????/// </summary> ???????Anonymous ???}}
Error.cshtml
@{ ???ViewBag.Title = "error"; ???Layout = "~/Views/Shared/_Layout.cshtml";}<h2>账号密码错误</h2>
Index.cshtml
@{ ???ViewBag.Title = "Index"; ???Layout = "~/Views/Shared/_Layout.cshtml";}<h2>登录成功,恭喜你登录成功</h2>
Login.cshtml
@{ ???ViewBag.Title = "登录"; ???Layout = "~/Views/Shared/_Layout.cshtml";}<div> ???<form action="tologin" method="post"> ???????<input type="text" name="UserName"/><br /> ???????<input type="password" name="Password" /><br/> ????????<input type="submit" value="提交" /> ???</form></div>
【ASP.NET】ASP.NET中权限验证使用OnAuthorization实现
原文地址:http://www.cnblogs.com/HDK2016/p/8086657.html