如何避免(或处理).net Core 3 Api中的自定义AuthorizationHandler中不存在的终结点

时间:2019-10-27 21:54:28

标签: api .net-core routes authorization endpoint

我已经创建了自定义的AuthorizationHandler。

public class VdsAuthorizationHandler : IAuthorizationHandler
    {
        private readonly IConfiguration _configuration;
        private readonly IHttpContextAccessor _httpContext;
        private readonly IHttpClientFactory _clientFactory;
        public VdsAuthorizationHandler(IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IHttpClientFactory clientFactory)
        {
            _configuration = configuration;
            _httpContext = httpContextAccessor;
            _clientFactory = clientFactory;
        }

        public Task HandleAsync(AuthorizationHandlerContext context)
        {
            UserRightsDefinition appUserRights = null;
            var authRequirement = context.PendingRequirements.Where(x => x is DenyAnonymousAuthorizationRequirement).FirstOrDefault();
            if (authRequirement != null)
            {
                if(_httpContext.HttpContext.User.Identity.IsAuthenticated)
                {
                    context.Succeed(authRequirement);
                } else
                {
                    context.Fail();
                    return Task.CompletedTask;
                }
            }
            var skipRequirement = context.PendingRequirements.Where(x => x is VdsSkipRequirement).FirstOrDefault();
            if (skipRequirement != null)
            {
                context.Succeed(skipRequirement);
            }
            else
            {
                var req = _clientFactory.CreateClient("Auth");
                var reqMessage = new HttpRequestMessage(HttpMethod.Get, "Auth/userrights");
                reqMessage.Content = new StringContent("", Encoding.UTF8, "application/json");
                var response = req.SendAsync(reqMessage);
                if (response.Result.IsSuccessStatusCode)
                {
                    var userRights = JsonConvert.DeserializeObject<Dictionary<string, UserRightsDefinition>>(response.Result.Content.ReadAsStringAsync().Result);
                    userRights.TryGetValue(_configuration.GetValue<string>("AppSettings:AppCode"), out appUserRights);
                }
                else
                {
                    throw new Vds404NotFoundException();
                }
            }

            if (appUserRights != null)
            {
                var pendingRequirements = context.PendingRequirements.ToList();
                foreach (var requirement in pendingRequirements)
                {
                    if (requirement is VdsPermissionsRequirement)
                    {
                        if (((VdsPermissionsRequirement)requirement).Permissions.Intersect(appUserRights.Permissions).Any())
                        {
                            context.Succeed(requirement);
                        }
                    }
                    else if (requirement is VdsGroupsRequirement)
                    {
                        if (((VdsGroupsRequirement)requirement).Groups.Intersect(appUserRights.Groups).Any())
                        {
                            context.Succeed(requirement);
                        }
                    }
                }
            }

            return Task.CompletedTask;
        }
    }
}

它可以完成其工作,但在以下情况下除外:如果我访问不存在的端点(例如/ api / fakeendpoint),则仍会调用HandleAsync。因此,我需要能够执行以下两项操作之一:

  • 要么评估请求的端点是否有效,要么;
  • 如果端点无效,避免调用HandleAsync

我该怎么做?

编辑:

如果有人可以确认,我可能已经找到了答案:

if(_httpContext.HttpContext.GetRouteData().Values.Count == 0)
{
    context.Fail();
    return Task.CompletedTask;
}

0 个答案:

没有答案