第五章 权限验证

源代码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

原文地址:https://www.cnblogs.com/zhaord/p/4899993.html