Skip to content

Instantly share code, notes, and snippets.

@jonathascosta
Last active July 16, 2020 07:16
Show Gist options
  • Save jonathascosta/7e27400d871af66133e87d2310abb7b2 to your computer and use it in GitHub Desktop.
Save jonathascosta/7e27400d871af66133e87d2310abb7b2 to your computer and use it in GitHub Desktop.
Checks when is the resource owner or someone with admin role
public interface IAuthorizationRule : IFilterMetadata
{
Task<bool> HasAccess(ActionExecutingContext context);
}
public class ResourceOwnerOrAdminAttribute : Attribute, IAuthorizationRule
{
private readonly string idArgumentName;
public ResourceOwnerOrAdminAttribute(string idArgumentName = "id")
{
this.idArgumentName = idArgumentName;
}
public async Task<bool> HasAccess(ActionExecutingContext context)
{
var someService = context.HttpContext.RequestServices.GetService<ISomeService>();
if (context.ActionArguments.TryGetValue(idArgumentName, out var argument) && argument is Guid id)
{
var obj = await someService.GetByIdAsync(id);
return context.HttpContext.User.HasClaim(c =>
(c.Type == ClaimTypes.Role && c.Value == "Admin") ||
(c.Type == ClaimTypes.UserId && c.Value == obj?.UserId));
}
return false;
}
}
public class ResourceOwnerOrAdminAuthorizationFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var filters = context
.Filters
.OfType<IAuthorizationRule>()
.Select(f => f.HasAccess(context));
var hasAccess = await Task.WhenAll(filters);
if (!hasAccess.All(a => a))
{
context.Result = new UnauthorizedResult();
return;
}
await next();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment