Authentication filters in ASP.NET Core 6 provide a powerful mechanism to implement custom authentication logic. They allow you to intercept incoming requests, validate user credentials, and grant or deny access based on specific criteria.
Here’s how you can create customized authentication filters in ASP.NET Core 6.
Create a Custom Authorization Attribute
You can create a custom authorization attribute by extending the AuthorizeAttribute or implementing IAuthorizationFilter or IAsyncAuthorizationFilter.
Example. Custom Attribute for Role-Based Authorization.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Linq;
public class CustomAuthorizeAttribute : Attribute, IAuthorizationFilter
{
private readonly string _role;
public CustomAuthorizeAttribute(string role)
{
_role = role;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var user = context.HttpContext.User;
if (!user.Identity.IsAuthenticated)
{
context.Result = new UnauthorizedResult();
return;
}
if (!user.IsInRole(_role))
{
context.Result = new ForbidResult();
return;
}
}
}
How to use it?
[CustomAuthorize("Admin")]
public IActionResult AdminOnlyAction()
{
return Ok("This is an Admin-only area.");
}
Custom Middleware for Authentication
For more flexibility, you can create custom middleware that inspects HTTP requests and enforces authentication.
Example. Custom Authentication Middleware.
using Microsoft.AspNetCore.Http;
using System.Linq;
using System.Threading.Tasks;
public class CustomAuthenticationMiddleware
{
private readonly RequestDelegate _next;
public CustomAuthenticationMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer "))
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
await context.Response.WriteAsync("Unauthorized");
return;
}
var token = authHeader.Substring("Bearer ".Length).Trim();
// Validate the token (you can use JWT or any other token mechanism)
if (token != "valid-token") // Replace with your validation logic
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
await context.Response.WriteAsync("Forbidden");
return;
}
await _next(context); // Pass to the next middleware
}
}
Register Middleware in Program. cs.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Add custom authentication middleware
app.UseMiddleware<CustomAuthenticationMiddleware>();
app.MapControllers();
app.Run();
Custom Policy-Based Authorization
Using ASP.NET Core’s policy-based authorization, you can define custom policies for advanced scenarios.
Define a Policy in the Program. cs.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
{
policy.RequireClaim("Role", "Admin");
});
});
var app = builder.Build();
Apply policy.
[Authorize(Policy = "AdminOnly")]
public IActionResult AdminOnlyAction()
{
return Ok("This is an Admin-only area.");
}
Add Custom Authorization Logic by Handler.
Create a custom requirement and handler
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
using System.Threading.Tasks;
public class CustomRoleRequirement : IAuthorizationRequirement
{
public string Role { get; }
public CustomRoleRequirement(string role)
{
Role = role;
}
}
public class CustomRoleHandler : AuthorizationHandler<CustomRoleRequirement>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
CustomRoleRequirement requirement)
{
if (context.User.HasClaim(c => c.Type == ClaimTypes.Role && c.Value == requirement.Role))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
Register the handler in services.
builder.Services.AddSingleton<IAuthorizationHandler, CustomRoleHandler>();
- Use custom attributes for lightweight authorization checks.
- Implement custom middleware for broader authentication handling.
- Use policy-based authorization for flexible and reusable rules.