在ASP.NET Core 中,授权过滤器(Authorization Filters)是用于在请求到达控制器操作方法之前,验证用户是否具有执行该操作的权限的一种机制。授权过滤器的主要作用是确保用户在访问控制器或操作方法时,已通过身份验证并且有足够的权限。
授权过滤器的工作原理
授权过滤器在 ASP.NET Core 中通常由IAuthorizationFilter
接口实现,或者通过更高级的授权机制(如AuthorizeAttribute
)进行配置。授权过滤器的执行时机位于所有其他类型过滤器之前,这意味着它们是第一个检查请求权限的过滤器。
1. 使用内置的[Authorize]
特性
[Authorize]
是 ASP.NET Core 中最常用的授权过滤器特性。它可以应用于控制器或操作方法,指示该操作需要特定的用户身份验证或授权。
基本用法:
-
全局授权:可以在
Startup.cs
中配置,要求所有控制器或操作都需要授权。public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options =>
{
// 将授权过滤器应用于所有控制器和操作
options.Filters.Add(new AuthorizeFilter());
});
} -
控制器级别授权:将
[Authorize]
特性应用于整个控制器,意味着控制器中的所有操作都需要授权。[Authorize]
public class MyController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult About()
{
return View();
}
} -
操作级别授权:将
[Authorize]
特性应用于单个操作方法,只要求特定操作需要授权。public class MyController : Controller
{
public IActionResult Index()
{
return View();
}
[Authorize]
public IActionResult About()
{
return View();
}
}
控制授权策略:
除了使用默认的[Authorize]
特性外,还可以根据特定的策略或角色进行授权。例如,你可以创建一个策略并将其与[Authorize]
特性结合使用。
// 在 Startup.cs 中配置授权策略
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});
services.AddControllersWithViews();
}
然后在控制器或操作方法中使用此策略:
[Authorize(Policy = "AdminOnly")]
public IActionResult AdminDashboard()
{
return View();
}
2. 自定义授权过滤器
除了使用[Authorize]
特性,ASP.NET Core 允许你创建自定义的授权过滤器,以便在请求管道中进行更多定制化的授权检查。
2.1 实现IAuthorizationFilter
接口
你可以通过实现IAuthorizationFilter
接口来创建一个自定义授权过滤器。这个接口定义了一个方法OnAuthorization
,它会在请求进入控制器之前调用。
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using System;
publicclassCustomAuthorizationFilter : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
// 检查用户是否已认证
if (context.HttpContext.User == null || !context.HttpContext.User.Identity.IsAuthenticated)
{
context.Result = new UnauthorizedResult(); // 返回 401 未授权
}
else
{
// 执行其他自定义授权逻辑
var userRole = context.HttpContext.User.FindFirst("Role")?.Value;
if (userRole != "Admin")
{
context.Result = new ForbidResult(); // 返回 403 禁止访问
}
}
}
}
2.2 注册自定义授权过滤器
在Startup.cs
中将自定义过滤器添加到服务容器:
public void ConfigureServices(IServiceCollection services)
{
// 添加自定义授权过滤器
services.AddControllersWithViews(options =>
{
options.Filters.Add(new CustomAuthorizationFilter());
});
}
这样,CustomAuthorizationFilter
就会应用于所有的控制器和操作方法。如果你只希望它应用于特定的控制器或方法,可以像使用[Authorize]
特性一样,应用自定义过滤器:
[ServiceFilter(typeof(CustomAuthorizationFilter))]
public class MyController : Controller
{
public IActionResult Index()
{
return View();
}
}
3. 异步授权过滤器
IAuthorizationFilter
接口有一个异步版本IAsyncAuthorizationFilter
,它用于处理需要异步操作(例如查询数据库、调用外部服务等)的授权检查。你只需要实现OnAuthorizationAsync
方法。
using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;
publicclassCustomAsyncAuthorizationFilter : IAsyncAuthorizationFilter
{
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
// 异步检查用户授权
var userIsAuthorized = await CheckUserAuthorizationAsync(context.HttpContext.User);
if (!userIsAuthorized)
{
context.Result = new UnauthorizedResult();
}
}
private async Task<bool> CheckUserAuthorizationAsync(ClaimsPrincipal user)
{
// 假设我们通过异步操作检查用户权限
await Task.Delay(100); // 模拟异步操作
return user.IsInRole("Admin");
}
}
4. 使用Policy
进行细粒度授权控制
通过定义授权策略(Authorization Policy),你可以在授权过滤器中做更细粒度的控制,例如根据用户的角色、声明等来决定是否允许访问某个资源。
4.1 配置授权策略
在Startup.cs
中,你可以定义策略:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
// 定义一个 "AdminOnly" 策略,要求用户拥有 "Admin" 角色
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});
services.AddControllersWithViews();
}
4.2 在控制器或操作方法中应用授权策略
[Authorize(Policy = "AdminOnly")]
public IActionResult AdminOnlyAction()
{
return View();
}
5. 全局授权过滤器
你可以在Startup.cs
中配置全局授权过滤器,使得所有的控制器和操作方法都应用某个授权规则。例如:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options =>
{
// 使所有操作都需要授权
options.Filters.Add(new AuthorizeFilter("AdminOnly"));
});
}
总结
[Authorize]
特性:最简单的授权方式,可以应用于控制器或操作方法。- 自定义授权过滤器:实现
IAuthorizationFilter
或IAsyncAuthorizationFilter
接口,进行更复杂的授权逻辑。 - 授权策略:允许你为不同的操作定义复杂的授权规则,例如根据角色或声明进行控制。
- 全局授权过滤器:可以在整个应用中应用一个授权策略。
授权过滤器的使用可以灵活地控制用户对资源的访问权限,在应用中根据需要选择适合的授权机制,确保安全性。