在 ASP.NET Core 8 中,授權策略(Policy)提供了一種靈活的方法來控制應用程式中的授權需求。你可以定義自訂的授權策略,並在控制器或動作方法中應用這些策略。以下是增加和使用授權策略的步驟:
步驟 1:設定授權策略
在 Program.cs
中,使用 AddAuthorization
方法來配置授權策略。例如,你可以定義一個基於角色的策略和一個基於自訂要求的策略。
var builder = WebApplication.CreateBuilder(args); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "yourissuer", ValidAudience = "youraudience", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("yoursecretkey")) }; }); builder.Services.AddAuthorization(options => { // 基於角色的策略 options.AddPolicy("RequireAdministratorRole", policy => policy.RequireRole("Administrator")); // 基於自訂要求的策略 options.AddPolicy("MinimumAge", policy => policy.Requirements.Add(new MinimumAgeRequirement(18))); }); builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeHandler>(); builder.Services.AddControllers(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
步驟 2:定義自訂授權需求和處理程序
如果你使用自訂要求,你需要定義需求和處理程序。例如,定義一個最低年齡要求的需求和處理程序:
using Microsoft.AspNetCore.Authorization; using System; using System.Security.Claims; using System.Threading.Tasks; public class MinimumAgeRequirement : IAuthorizationRequirement { public int MinimumAge { get; } public MinimumAgeRequirement(int minimumAge) { MinimumAge = minimumAge; } } public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeRequirement requirement) { if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth)) { return Task.CompletedTask; } var dateOfBirth = Convert.ToDateTime(context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth).Value); int calculatedAge = DateTime.Today.Year - dateOfBirth.Year; if (dateOfBirth > DateTime.Today.AddYears(-calculatedAge)) { calculatedAge--; } if (calculatedAge >= requirement.MinimumAge) { context.Succeed(requirement); } return Task.CompletedTask; } }
步驟 3:在控制器或動作方法中使用策略
你可以使用 [Authorize]
屬性來應用策略。例如:
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; [Route("api/[controller]")] [ApiController] public class SampleController : ControllerBase { // 需要 Administrator 角色 [Authorize(Policy = "RequireAdministratorRole")] [HttpGet("admin")] public IActionResult GetForAdmin() { return Ok("This is an admin endpoint."); } // 需要滿足 MinimumAge 策略 [Authorize(Policy = "MinimumAge")] [HttpGet("age")] public IActionResult GetForAge() { return Ok("This is an age-restricted endpoint."); } }
完整範例
以下是完整的設定、需求和處理程序,以及控制器範例:
// Program.cs var builder = WebApplication.CreateBuilder(args); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "yourissuer", ValidAudience = "youraudience", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("yoursecretkey")) }; }); builder.Services.AddAuthorization(options => { options.AddPolicy("RequireAdministratorRole", policy => policy.RequireRole("Administrator")); options.AddPolicy("MinimumAge", policy => policy.Requirements.Add(new MinimumAgeRequirement(18))); }); builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeHandler>(); builder.Services.AddControllers(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run(); // MinimumAgeRequirement.cs public class MinimumAgeRequirement : IAuthorizationRequirement { public int MinimumAge { get; } public MinimumAgeRequirement(int minimumAge) { MinimumAge = minimumAge; } } // MinimumAgeHandler.cs public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeRequirement requirement) { if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth)) { return Task.CompletedTask; } var dateOfBirth = Convert.ToDateTime(context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth).Value); int calculatedAge = DateTime.Today.Year - dateOfBirth.Year; if (dateOfBirth > DateTime.Today.AddYears(-calculatedAge)) { calculatedAge--; } if (calculatedAge >= requirement.MinimumAge) { context.Succeed(requirement); } return Task.CompletedTask; } } // SampleController.cs [Route("api/[controller]")] [ApiController] public class SampleController : ControllerBase { [Authorize(Policy = "RequireAdministratorRole")] [HttpGet("admin")] public IActionResult GetForAdmin() { return Ok("This is an admin endpoint."); } [Authorize(Policy = "MinimumAge")] [HttpGet("age")] public IActionResult GetForAge() { return Ok("This is an age-restricted endpoint."); } }