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