Как избежать (или обработать) несуществующие конечные точки в пользовательском AuthorizationHandler в .net Core 3 Api - PullRequest
0 голосов
/ 28 октября 2019

Я создал свой собственный 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;
}
...