So, you want to protect your ASP.NET Web API endpoints with custom rules. How do you get it done? You’ll need two pieces of code.
- A class implementing IAuthorizationFilter with your custom rules implemented in public void OnAuthorization(AuthorizationFilterContext context)
- An attribute class inheriting from TypeFilterAttribute, passing the type of your step 1 class
It’s honestly much simpler when you see the code in practice. Here’s an example in action that I built to validate that the account ID appearing in the URL is owned by the authenticated tenant.
IAuthorizationFilter Implementation
using MemberPlus.Core.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace MemberPlus.AdminAPI
{
public class AuthorizeAccountFilter : IAuthorizationFilter
{
public AuthorizeAccountFilter(AuthorizationService authService)
{
this.authorizationService = authService;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var accountId = Guid.Parse((string)context.RouteData.Values["accountId"]!);
var tenantId = context.HttpContext.GetTenantId();
var authorizationResult = authorizationService.AuthorizeAccountForTenant(tenantId, accountId).Result;
if (!authorizationResult)
{
context.Result = new ForbidResult();
}
}
private readonly AuthorizationService authorizationService;
}
}
TypeFilterAttribute Implementation
using Microsoft.AspNetCore.Mvc;
namespace MemberPlus.AdminAPI
{
public class AuthorizeAccountAttribute : TypeFilterAttribute
{
public AuthorizeAccountAttribute() : base(typeof(AuthorizeAccountFilter))
{
}
}
}
Conclusion
As you can see, this implementation can be completed in two easy parts. Happy coding!