zoukankan      html  css  js  c++  java
  • 第五章 权限验证

    源代码GitHub:https://github.com/ZhaoRd/Zrd_0001_AuthorityManagement

    1.介绍

            权限验证过程中,如何判断所有过程是一个难点,少判断一个过程,那么这个验证就不完整。

           本节主要介绍了在这个Demo中使用的验证原理以及过程

    2.验证原理

            在上一章中说道验证过程主要是依赖mvc的controller和action,通过attribute采集信息。

            在mvc中,添加IAuthorizationFilter接口的实现类,实现OnAuthorization方法,所有的权限验证均在这个方法内完成,在FilterConfig类中注册该实现,代码如下:5b85431b-8086-4409-9474-b09e753fbb3c

            我们通过判断AllowAnonymousAttribute是不是匿名访问,通过判断SystemModelAttribute是不是系统模块,通过判断NeedLoginedAttribute是不是需要登录访问,通过判断PermissionSettingAttribute是不是具有权限限制。

    3.验证过程

    1. 匿名访问

    a43dd9d6-1b7f-4c55-be65-44a03c5089a4

    2. 非系统模块

    d9a522c0-1667-49d5-a19e-4bc095adfca8

    3. 需要登录访问,用户未登录这返回HttpUnauthorizedResult

    51470c23-f74e-4903-93f3-815e6029c1c8

    4. 用户已登录,但是action是没有权限限制的,也通过

    9705191f-d18c-49dc-910e-cd2396fd01b2

    5. 判断权限

    dbaf19f3-0a71-46b7-a527-90849712b51b

    4.代码

     

    namespace AuthorityManagement.Web.Filters
    {
        using System;
        using System.Text;
        using System.Web.Mvc;
        using System.Web.Security;
    
        using Presentation.Attributes;
        using Presentations;
        using Presentations.Attributes;
    
        using Skymate;
        using Skymate.Engines;
    
        using AllowAnonymousAttribute = System.Web.Http.AllowAnonymousAttribute;
    
        /// <summary>
        /// The my authorization filter.
        /// </summary>
        public class MyAuthorizationFilter : IAuthorizationFilter
        {
            /// <summary>
            /// The on authorization.
            /// </summary>
            /// <param name="filterContext">
            /// The filter context.
            /// </param>
            public void OnAuthorization(AuthorizationContext filterContext)
            {
                var actionDescriptor = filterContext.ActionDescriptor;
                var controllerDescriptor = filterContext.ActionDescriptor.ControllerDescriptor;
    
                // 匿名一律绿灯通行
                var isAllowAnonymou = actionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), false);
                if (isAllowAnonymou)
                {
                    return;
                }
    
                // 非系统模块,一律通行
                var isSystemModel = controllerDescriptor.IsDefined(typeof(SystemModelAttribute), false);
                if (!isSystemModel)
                {
                    return;
                }
    
                // 需要登录访问
                var isNeedLogined = actionDescriptor.IsDefined(typeof(NeedLoginedAttribute), false)
                                    || controllerDescriptor.IsDefined(typeof(NeedLoginedAttribute), false);
    
                var userId = string.Empty;
                if (isNeedLogined)
                {
                    var authCookie = filterContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
                    if (authCookie == null)
                    {
                        filterContext.Result = new HttpUnauthorizedResult();
                        return;
                    }
    
                    var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    
                    if (authTicket == null || authTicket.UserData == string.Empty)
                    {
                        filterContext.Result = new HttpUnauthorizedResult();
                        return;
                    }
    
                    userId = authTicket.UserData;
                }
    
                var isSetPermission = actionDescriptor.IsDefined(typeof(PermissionSettingAttribute), false);
    
                // 如果没有设置具体权限,一律通过
                if (!isSetPermission)
                {
                    return;
                }
    
                var systemModelAttribute = (SystemModelAttribute)controllerDescriptor.GetCustomAttributes(typeof(SystemModelAttribute), false)[0];
                var permissionSetting =
                    (PermissionSettingAttribute)
                    actionDescriptor.GetCustomAttributes(typeof(PermissionSettingAttribute), false)[0];
    
                var datatokens = filterContext.RequestContext.RouteData.DataTokens["area"];
    
                // 计算area
                var areaName = datatokens == null ? string.Empty : datatokens.ToString();
    
                var groupName = systemModelAttribute.GroupName ?? areaName;
    
                var permissionService = EngineContext.Current.Resolve<IPermissionService>();
    
                var isAllowed = permissionService.VerifyAuthority(new VerifyAuthorityInputDto()
                                                                      {
                                                                          LoginUserId = Guid.Parse(userId),
                                                                          GroupName = groupName,
                                                                          PermissionValue = permissionSetting.PermissionValue,
                                                                          SystemModelName = systemModelAttribute.Name
                                                                      });
    
                if (!isAllowed && filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    filterContext.Result = new JsonResult
                                               {
                                                   Data = OperationResult.Error("无操作权限"),
                                                   ContentEncoding = Encoding.UTF8,
                                                   JsonRequestBehavior = JsonRequestBehavior.AllowGet
                                               };
                    return;
                }
    
                if (!isAllowed)
                {
                    filterContext.HttpContext.Response.Redirect("~/401.html");
                }
            }
        }
    }
    

      

    推荐QQ群:

    278252889(AngularJS中文社区)

    5008599(MVC EF交流群)

    134710707(ABP架构设计交流群 )

    59557329(c#基地 )

    230516560(.NET DDD基地 )

    本人联系方式:QQ:351157970

  • 相关阅读:
    POJ 3041 Asteroids 二分图匹配
    ZOJ 3705 Applications 模拟
    UNIX环境高级编程(第3版)
    明清美文四卷本(共四册)
    卑鄙的圣人:曹操(全10册)
    爱丽丝梦游仙境
    我在大清官场30年
    乌合之众:大众心理研究
    Java多线程编程实战指南
    Linux就该这么学
  • 原文地址:https://www.cnblogs.com/zhaord/p/4899993.html
Copyright © 2011-2022 走看看