asp.net mvc5 基于角色的权限验证

第一步 登录的时候写入标准的权限信息到Cookie中.
第二步 Global.asax 文件中增加从cookie中取得权限信息的代码
第三步 使用 [Authorize(Roles = “admin”)] 标注权限所需角色

   [HttpPost]
        public ActionResult DoLogin(string username, string password, string yzm, string returnUrl)
        {
            SysUser user = DB.FirstOrDefault(x => x.UserID == username && x.UserPassword == password);
            if (Session["code"] != null && Session["code"].ToString().ToUpper().Trim().Equals(yzm.ToUpper()))
            {
                if (user != null)
                {
                   // FormsAuthentication.SetAuthCookie(username, true);//比较差的方法,不能保存角色信息
                    SetFormsAuthentication(username,true, "admin");//admin 是角色名
                    //FormsAuthentication.SignOut();
                    if (!String.IsNullOrEmpty(returnUrl)) return Redirect(returnUrl); 
                    else return Redirect("/");
                }
                else
                {
                    ViewBag.Message = "用户名或密码错误!";
                }
            }
            else
            {
                //登陆失败,提示错误信息
                ViewBag.Message = "验证码错误!";
            }
            return View("Index");
        }

		//将登录信息写入Cookie
        public   void SetFormsAuthentication(string username, bool isPersistent, string roles)
        {
            roles = string.IsNullOrEmpty(roles) ? string.Empty : roles;

            //创建票证
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
                username,
                DateTime.Now,
                DateTime.Now.AddMinutes(720),
                isPersistent,
                roles,
                FormsAuthentication.FormsCookiePath);

            // 加密票证
            string encTicket = FormsAuthentication.Encrypt(ticket);

            // 创建cookie
            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
            {
                HttpOnly = true,
                Path = FormsAuthentication.FormsCookiePath,
                Secure = false
            };
            if (ticket.IsPersistent)
            {
                cookie.Expires = ticket.Expiration;
            }
            Response.Cookies.Add(cookie);
        }

Global.asax 文件中增加从cookie中恢复权限信息的代码,

   public class MvcApplication : System.Web.HttpApplication
    {

        public MvcApplication()
        {
            AuthorizeRequest += new EventHandler(MvcApplication_AuthorizeRequest);
        }

        void MvcApplication_AuthorizeRequest(object sender, EventArgs e)
        {
 
            var url = Request.RawUrl;
            string cookieName = FormsAuthentication.FormsCookieName;
            HttpCookie authCookie = Context.Request.Cookies[cookieName];
            FormsAuthenticationTicket authTicket = null;
            try
            {
                authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            }
            catch (Exception ex)
            {
                return;
            } 
            string[] roles = authTicket.UserData.Split(new char[] { ','});//如果存取多个角色,我们把它分解 
            FormsIdentity id = new FormsIdentity(authTicket); 
            GenericPrincipal principal = new GenericPrincipal(id, roles);
            Context.User = principal;//存到HttpContext.User中

        }
}

第三步 使用, 只需要在每个Action上面 加个注解属性. [Authorize(Roles = “admin”)]
这样只有是admin角色的用户才能访问. 这是 Authorize 类中定义的.

    public class DefaultController : Controller
    {
        // GET: Default
        [Authorize(Roles = "admin")] //这样用就可以了. admin 是角色名
        public ActionResult Index()
        {
            return View();
        }
    }

看到这里, 估计有些人会觉得这个有点鸡肋. 我们设计系统的时候肯定不知道角色有那些的, 这样就把角色的个数框定死在代码里了.

有没有什么方法能够使得后期的角色可以动态增加, 而不修改系统呢?
经过修改,确实是可以做到的. 使用方法如下.

    public class DefaultController : Controller
    {
        // GET: Default
        //[App_Start.MVC.Filters.UserAuthorize( RightName ="121")]
        [RightAuthorize(NeedRightId = "CustomeView", RightDesc= "查看客户信息")]
        public ActionResult Index()
        {
            return View();
        }
    }

RightAuthorize这个类是自定定义的, 只需要继承自AuthorizeAttribute 就可以了.

using Common;
using MK.DBModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MKDataCenter 
{
        /// <summary>
        /// 所需权限属性
        /// </summary>
        public class RightAuthorize : AuthorizeAttribute
        {
 

        /// <summary>
        /// 权限注释,可通过反射自动添入到权限系统中.方便用户查看.
        /// </summary>
        public string RightDesc { get; set; }
        

        /// <summary>
        /// 访问本Action所需权限Id
        /// </summary>
        public string NeedRightId { get; set; }

        /// <summary>
        /// 权限列表
        /// </summary>
        private List<SysRoleRightRelation> Rights ;

        private static ICache AllRightsCache = new SystemCache();

        /// <summary>
        /// 请求授权时执行
        /// </summary>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
                // 判断是否已经验证用户
                if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
                {
                    // 如果没有验证则跳转到LogOn页面
                    filterContext.HttpContext.Response.Redirect("~/BaseApp/Login/Index");
                    return;
                }

                var ticket = ((System.Web.Security.FormsIdentity)filterContext.HttpContext.User.Identity).Ticket;
                var roles = ticket.UserData.Split(',');
                //去缓存查数据
                var allRights = AllRightsCache.GetCache<List<MK.DBModel.SysRoleRightRelation>>("AllRights");
                if (allRights == null)
                {
                      //重新加载缓存权限数据
                      allRights = new DbHelp.Base.DbBase<SysRoleRightRelation>().AsQueryable().ToList();
                      AllRightsCache.SetCache("AllRights", allRights);
                }

                this.Rights = allRights
                                .Where( a=>roles.Contains( a.RoleID ) )
                                .ToList();
                
                base.OnAuthorization(filterContext);
            }
            /// <summary>
            /// 自定义授权检查(返回False则授权失败)
            /// </summary>
            protected override bool AuthorizeCore(HttpContextBase httpContext)
            { 
                if (httpContext.User.Identity.IsAuthenticated)
                { 
                    return this.Rights.Where(a=>a.RightID == this.NeedRightId).Count()>0; 
                }
                else
                {
                    //进入HandleUnauthorizedRequest
                    return false;
                }

            }

            /// <summary>
            /// 处理授权失败的HTTP请求
            /// </summary>
            protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
            {
                filterContext.Result = new ViewResult { ViewName = "AuthorizationFailView" };
            }
        }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值