• 【ASP.NET】ASP.NET中权限验证使用OnAuthorization实现


    在项目开发中,通常我们都会涉及到用户登录才能访问的网页,比如购物网站,我们浏览商品,添加购物车(以前开发的时候在这里就需要登录用户,但是现在有了缓存的实现,这里可以将商品加入缓存,等到结账的时候再登录),选择结账的时候需要登录,那么这时候我们需要跳转到登录页面登录,登录之后还可以回到记录下来的原始的页面,那么这之后我们有好几种方法可以实现这种效果,下面笔者举例两种:

    第一种:登录模块不管怎么样都是统一的,就是在每个需要登录的方法里面判断用户是否登录,如果没有登录,则跳转登录,这种的缺点是工作量大,代码冗余。

    第二种:使用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
                {
                        if (System.Web.HttpContext.Current.Request.Cookies["settings"] == null) {
                            return false;
                        }
                    //检查Cookies
                    String cookie_UserName = System.Web.HttpContext.Current.Request.Cookies["settings"]["UserName"];
                    String cookie_Password = System.Web.HttpContext.Current.Request.Cookies["settings"]["Password"];
                    //检查用户名和密码
                     if (cookie_UserName == null || cookie_Password == null)
                     {
                         return false;
                     }
                     else {
                         //在数据库中检查
                         if ("abc".Equals(cookie_UserName) && "123".Equals(cookie_Password)) {
                         //把用户名和密码放到Session中
                        Session.Add("UserName", cookie_UserName);
                        Session.Add("Password", cookie_Password);
                             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.cs

    这里的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中
                    Session.Add("UserName", "abc");
                    Session.Add("Password", "123");
                    //放到Cookie中,可以进行加密处理
                    HttpCookie myCookie = new HttpCookie("settings");
                    myCookie["UserName"] = user;
                    myCookie["Password"] = password;
                     System.Web.HttpContext.Current.Response.Cookies.Add(myCookie);
                     HttpContext.Response.Redirect("~/Manager/Index");
                }
                return View("Error");
            }
    
            [Access(IsAccess = AccessEnum.Anonymous)]
            public ActionResult Login()
            {
                return View();
            }
            [Access(IsAccess = AccessEnum.Login)]
            public ActionResult LoginOff(){
                  //清除Session信息
                  Session.Clear();
                  //清除Cookie信息
                  HttpCookie myCookie = new HttpCookie("settings");
                  myCookie.Expires = DateTime.Now;
                  System.Web.HttpContext.Current.Response.Cookies.Add(myCookie);
                  HttpContext.Response.Redirect("~/Manager/index");
            }
        }
    }    
    ManagerController.cs

    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
        }
    }
    AccessAttribute.cs

    Error.cshtml

    @{
        ViewBag.Title = "error";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>账号密码错误</h2>
    Error.cshtml

    Index.cshtml

    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>登录成功,恭喜你登录成功</h2>
    Index.cshtml

    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>
    Login.cshtml
  • 相关阅读:
    antd Icon
    antd button
    tree 向上查找(更新删除后页面的数据)
    tree 向下查找 (删除整条tree)
    tree结构统一修改属性名(递归)
    json转换为tree对象(递归)
    python测试题
    c函数练习
    飞机一只
    python1119作业1
  • 原文地址:https://www.cnblogs.com/HDK2016/p/8086657.html
Copyright © 2020-2023  润新知