您的当前位置:首页正文

ASP.NET Core-示例代码-权限验证-过滤器(Filter)

2024-11-29 来源:个人技术集锦

在前端或者通过工具调用接口时,判断该用户是否有权限

  • 前端展示

前端页面功能按钮请求接口设置

前端的功能权限设置

  • 后端权限验证代码
  • 创建接口权限过滤器文件
namespace JWProject.Api.Infrastructure.Filters
{
    /// <summary>
    /// 接口权限
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class RoleFilter : BaseActionFilter
    {

        /// <summary>
        /// 执行方法之前
        /// </summary>
        /// <param name="context"></param>
        /// 
        public override async void OnActionExecuting(ActionExecutingContext context)//继承ActionFilterAttribute类,可获取接口数据
        {

            //base.OnActionExecuting(context);
            //return;

            var actionName = context.ActionDescriptor.DisplayName;

            using IServiceScope scope = context.HttpContext.RequestServices.CreateScope();
            IRmissionMService _rmissionMService = scope.ServiceProvider.GetService<IRmissionMService>();

            //0.獲取方法,控制器,區域,請求方式

            string httpMethod = context.HttpContext.Request.Method.ToUpper();

            string routeTemplate = context.ActionDescriptor.AttributeRouteInfo.Template;

            string apidata = "/" + routeTemplate;

            string user = context.HttpContext.User.Claims.First().Value;



            if (string.IsNullOrWhiteSpace(user))
            {
                //判断user如果为空则提示没有登录
                context.Result = new JsonResult(ApiResult.error(ApplicationErrorCodeEnum.SYS_NOT_VALID_TOKEN));
            }
            RequestParamsDto reqParams = new RequestParamsDto()
            {
                apidata = apidata,
                company_id = context.HttpContext.User.Claims.FirstOrDefault(t => t.Type == "company").Value,
                method = httpMethod,
            };
                var data = await _rmissionMService.ExistRole(user, reqParams);//判断有无权限
                if (data)
                {
                    base.OnActionExecuting(context);
                    return;
                }
                else//后续的判断可以根据自己情况修改 
                {
                if (reqParams.apidata.Contains("dataList"))
                {
                    context.Result = new JsonResult(ApiResult.error(ApplicationErrorCodeEnum.SYS_NOT_VALID_REQUEST));

                    base.OnActionExecuting(context);
                }
                else
                {
                    context.Result = new JsonResult(ApiResult.error(ApplicationErrorCodeEnum.SYS_NOT_VALID_REQUESTS));

                    base.OnActionExecuting(context);
                }

                   
                }
            

            

        }

        /// <summary>
        /// 执行方法之后
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            base.OnActionExecuted(context);
        }


    }
}
  /// <summary>
  /// 判断是否有权限
  /// </summary>
  /// <param name="usercode"></param>
  /// <param name="paramsDto"></param>
  /// <returns></returns>
  public async Task<bool> ExistRole(string usercode, RequestParamsDto paramsDto)
  {
      try
      {
          //用户id找到权限
          StaffModel staffModel = new StaffModel()
          {
              ST_CODE = usercode,
              ST_COMPANY_ID = paramsDto.company_id
          };
          PersonnelInformationModel informationModel = new PersonnelInformationModel()
          {
              ST_COMPANY_ID = paramsDto.company_id
          };

          var userrole = await _mergeRepository.GetDataByUserId(staffModel, informationModel);//获取用户权限
          var logkey = GlobalConstants.REDIS_LOGIN + userrole.Staff.ST_ID; // # 链接redis //缓存使用用户id拼接(唯一)
          var database1 = _redisContext.GetCache<LoginRedis>(logkey);//去缓存找对对应用户的权限
          if (database1.Identity == 1)// 如果是超级用户
          {
              return true;//不要判断直接访问接口

          }
          //根据当前用户的权限id去缓存找数据
          string roleKey = GlobalConstants.REDIS_ROLE + paramsDto.company_id + ":" + userrole.personnel.ST_PERMISSION;
          List<RidesQuery> data = _redisContext.GetCache<List<RidesQuery>>(roleKey);

          //如果缓存没有数据
          if (data == null)
          {
              //把数据查出来
              data = await GetRides(userrole.personnel.ST_PERMISSION, paramsDto.company_id);
              //权限写入缓存
              _redisContext.SetCache(roleKey, data, DateTime.Now.AddDays(GlobalConstants.REDIS_ROLE_TIME));//把数据给缓存
          }
          foreach (var item in data)
          {

              if (!string.IsNullOrWhiteSpace(item.Path) && !string.IsNullOrWhiteSpace(item.Method) && item.Type == 0 &&
                  item.Path.ToUpper() == paramsDto.apidata.ToUpper() && item.Method.ToUpper() == paramsDto.method.ToUpper() && item.Role == 1)//缓存的路径和接口返回的路径对比权限
              {
                  return true;
              }
          }
          return false;
      }
      catch (Exception ex)
      {
          _loggerContext.Error(ex.Message, ex);
          return false;
      }
  }
  • 给指定接口使用过滤器 [RoleFilter]

  • 全部接口使用过滤器
      services.AddControllers(option =>
      {
          option.EnableEndpointRouting = false;
          option.Filters.Add(typeof(RoleFilter));
       

      }).AddJsonOptions(options =>
      {
          options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
          //忽略null字段
          options.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;
      });

以上就是过滤器的创建与使用 

还有关于用户在请求接口时,判断该用户是否有权限,请看下一篇文章

这样处理可以保证用户在登录的同时,管理员将账号停用则该用户无法继续使用系统

显示全文