I have created my custom 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;
}
}
}
It does what it has to do, except in one case : If I access a non-existing endpoint (ex. /api/fakeendpoint), HandleAsync is still called. So I need to be able to do one of these 2 things :
- Either evaluate if the requested endpoint is valid or;
- Avoid calling HandleAsync if the endpoint is invalid
How can I do that?
EDIT:
I might have found an answer, if anyone can confirm :
if(_httpContext.HttpContext.GetRouteData().Values.Count == 0)
{
context.Fail();
return Task.CompletedTask;
}