码迷,mamicode.com
首页 > Web开发 > 详细

ASP.NET MVC权限控制思路

时间:2019-03-19 01:27:36      阅读:366      评论:0      收藏:0      [点我收藏+]

标签:方法   object   显示   封装   源码   一起   ext   因此   for   

在系统开发的时候一个老生常谈的权限管理问题,翻阅了很多的网络资料,但是总感觉离实际使用还有一段距离,其实权限控制无非就几个“请求、页面按钮、字段显示”, 对于前端权限就需要配合JS了, 这里主要展示我这些年来一直使用的一个关于权限管理的案例,如果你只是写一个简单的CMS系统,那么下面代码其实拷贝就可以用了,如果是需要进行较大型系统开发就需要进一步封装, 下面是我的思路,写的不好大家勿喷哈,有不同意见的留下一起探讨。

1、在MVC开发时路由中包含了我们所有请求信息(Controller、Action、URL全文),而MVC又提供了过滤器的机制,因此我们将权限管理封装到过滤其中。首先把每个Controller的继承封装一个BaseController,这个Controller基类可以编写一些直接调用的方法,例如Session等。

    /// <summary>
    /// 系统基础控制器类
    /// </summary>
    public abstract class BaseUIController : Controller
    {
        /// <summary>
        /// 页面初始化过程
        /// </summary>
        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            requestContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            base.Initialize(requestContext);
        }

        /// <summary>
        /// 内容返回
        /// </summary>
        /// <param name="content">特定内容供JS参考是否含流程定义等动作。</param>
        /// <param name="contentType"></param>
        /// <param name="contentEncoding"></param>
        /// <returns></returns>
        protected override ContentResult Content(string content, string contentType, Encoding contentEncoding)
        {
            return base.Content(content, contentType, contentEncoding);
        }

        /// <summary>
        /// 登陆用户ID (Session存储)
        /// </summary>
        public long LoginedUserID
        {
            get
            {
                object UID = Ant.UI.Controls.SessionConfig.GetSession("UID");
                if (Session == null || UID == null)
                    return -1;
                else
                {
                    return (long)UID;
                }
            }
            set
            {
                Ant.UI.Controls.SessionConfig.SetSession("UID", value);
            }
        }
        
        /// <summary>
        /// 获取URL参数值,返回 NULL 或 值
        /// </summary>
        /// <param name="keyName">参数名</param>
        public string RequestUrlParams(string keyName)
        {
            if (Array.IndexOf(Request.QueryString.AllKeys, keyName) >= 0)
                return Request.QueryString[keyName].ToString();
            else
                return null;
        }
    }

2、这个时候我们编写一个过滤器,在这个过滤器中可以在请求的Controller中获取controller名称和action名称。 有了这两个名称就能定位到具体的页面了,当然在得到页面之前我们可以判断用户是否已经登录。而页面权限页已经用数据库保存起来:A用户或R角色对某一个Controller/Action的页面(这个页面可能是新增信息、修改、删除信息的请求链接)是否有访问权限。

    /// <summary>
    /// 用户登录过滤器
    /// </summary>
    public class UserLoginedFilter : AuthorizeAttribute
    {
        public string name { get; set; }
        /// <summary>
        /// 页面授权过程(验证用户登录状态)
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            UI.Controllers.BaseUIController _ControllerObj = (UI.Controllers.BaseUIController)filterContext.Controller;
            string controllerStr = _ControllerObj.ControllerContext.RouteData.Values["controller"].ToString();
            string actionStr = _ControllerObj.ControllerContext.RouteData.Values["action"].ToString();
            
            //用户尚未登陆 或 登陆超时。
            if (_ControllerObj.LoginedUserID == -1)
            {
                UserError.LoginError();
            }
            // 权限验证 根据 Controller 与 Action(这里可以将权限缓存取出来进行用户匹配,如果被拒绝可以抛出异常)
            else if ( controllerStr.ToLower() == "admin" && actionStr.ToLower() == "login")
            {
                throw new HttpException("权限验证。" + _ControllerObj.ControllerContext.Controller.ToString());
            }

            base.OnAuthorization(filterContext);
        }
    }

3、此时页面调用时就不用在每个Action中编写权限验证代码啦(有些权限验证的源码会在Action上增加过滤器,为了偷懒硬是想方设法把权限封装成直接在Controller类上添加一次过滤器就能完成的实现)

    [UserLoginedFilter]
    public class AdminController : UI.Controllers.BaseUIController
    {
        /// <summary>
        /// 登陆(登陆页面不需要权限验证,增加AllowAnonymous特性)
        /// </summary>
        [AllowAnonymous]
        public ActionResult Login(FormCollection form)
        {
            return View();
        }

        /// <summary>
        /// 主界面
        /// </summary>
        public ActionResult Index()
        {
            return View();
        }
    }

上面只是我在系统开发过程中对于权限管理的一个思路,也实实在在的应用到了一些系统中,当然上面这些代码只能勉强判断是否登陆,如果你需要对数据权限、页面权限、字段权限进行管理那么就需要进一步的扩展。如果需要在抛出异常后将异常信息友好的返回给客户端,那你仍然需要在Global中捕获返回状态码以及错误信息。因此我说这只是我的一个思路,路过的朋友给我建议。多谢!

 

ASP.NET MVC权限控制思路

标签:方法   object   显示   封装   源码   一起   ext   因此   for   

原文地址:https://www.cnblogs.com/EvanYu/p/10556171.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!