zoukankan      html  css  js  c++  java
  • 【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类继承了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");
            }
        }
    }    
    复制代码

    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>
    复制代码
  • 相关阅读:
    用 ArcMap 发布 ArcGIS Server FeatureServer Feature Access 服务 PostgreSQL 版本
    ArcMap 发布 ArcGIS Server OGC(WMSServer,MapServer)服务
    ArcScene 创建三维模型数据
    ArcMap 导入自定义样式Symbols
    ArcMap 导入 CGCS2000 线段数据
    ArcMap 导入 CGCS2000 点坐标数据
    ArcGis Server manager 忘记用户名和密码
    The view or its master was not found or no view engine supports the searched locations
    python小记(3)操作文件
    pytest(2) pytest与unittest的区别
  • 原文地址:https://www.cnblogs.com/wfy680/p/12402910.html
Copyright © 2011-2022 走看看