0Pricing
C# Academy · 课时

自定义授权要求

构建自定义要求和处理程序。

自定义授权要求 是 CoddyKit 上的免费 C# Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。

内置功能不足以应对时

有些规则无法通过 RequireRole 或 RequireClaim 表达——例如“年龄必须至少为 18 岁”或“必须拥有此资源”。

对于这些规则,您需要编写自定义要求和处理程序。

// Rule: user must be older than a configurable minimum age

IAuthorizationRequirement

要求是一种携带规则数据的标记。它实现了空的 IAuthorizationRequirement 接口。

public class MinimumAgeRequirement : IAuthorizationRequirement
{
    public int MinimumAge { get; }
    public MinimumAgeRequirement(int minimumAge) =>
        MinimumAge = minimumAge;
}

AuthorizationHandler

处理程序包含逻辑。请从 AuthorizationHandler<TRequirement> 派生,并重写 HandleRequirementAsync。

public class MinimumAgeHandler
    : AuthorizationHandler<MinimumAgeRequirement>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        MinimumAgeRequirement requirement)
    {
        // logic goes here
        return Task.CompletedTask;
    }
}

使要求成功

在处理程序内部检查用户的声明。如果满足规则,请调用 context.Succeed(requirement)。如果不满足,只需直接返回,不要调用它。

var dobClaim = context.User.FindFirst("birthdate");
if (dobClaim is null) return Task.CompletedTask;

var dob = DateTime.Parse(dobClaim.Value);
int age = DateTime.UtcNow.Year - dob.Year;
if (dob > DateTime.UtcNow.AddYears(-age)) age--;

if (age >= requirement.MinimumAge)
    context.Succeed(requirement);

return Task.CompletedTask;

调用 Succeed,而不是 Fail

满足要求时,优先调用 Succeed,否则不执行任何操作。只有当您希望无论同一要求的其他处理程序如何处理都确保失败时,才调用 context.Fail()。

// Soft: let other handlers also try
if (ok) context.Succeed(requirement);

// Hard: force failure no matter what
if (blocked) context.Fail();

注册处理程序

将处理程序作为 IAuthorizationHandler 注册到 DI 中。除非处理程序依赖作用域服务,否则通常应将其注册为单例。

builder.Services.AddSingleton<
    IAuthorizationHandler, MinimumAgeHandler>();

附加到策略

使用 AddRequirements(或 Requirements.Add)将要求添加到命名策略。系统会根据类型自动匹配处理程序。

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AtLeast18", policy =>
        policy.AddRequirements(new MinimumAgeRequirement(18)));
});

使用策略

像使用其他命名策略一样应用它。

[Authorize(Policy = "AtLeast18")]
[HttpGet("age-restricted")]
public IActionResult Restricted() => Ok();

基于资源的授权

如果要针对特定实例进行授权(例如“只有文档所有者可以编辑”),请使用资源重载。资源会传入处理程序上下文。

public class OwnerHandler
    : AuthorizationHandler<OwnerRequirement, Document>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        OwnerRequirement requirement,
        Document resource)
    {
        var userId = context.User.FindFirstValue(
            ClaimTypes.NameIdentifier);
        if (resource.OwnerId.ToString() == userId)
            context.Succeed(requirement);
        return Task.CompletedTask;
    }
}

调用 IAuthorizationService

基于资源的检查会在操作内部通过注入的 IAuthorizationService 以命令式方式运行。

public async Task<IActionResult> Edit(int id)
{
    var doc = await _db.Documents.FindAsync(id);
    var result = await _authz.AuthorizeAsync(
        User, doc, "DocumentOwner");
    if (!result.Succeeded) return Forbid();
    return Ok(doc);
}

一个要求对应多个处理程序

一个要求可以拥有多个处理程序;只要任意一个处理程序成功,该要求就满足了。这样可以清晰地表示 OR 条件(除非某个处理程序调用了 Fail)。

// e.g. allow if owner OR if admin role
services.AddSingleton<IAuthorizationHandler, OwnerHandler>();
services.AddSingleton<IAuthorizationHandler, AdminOverrideHandler>();

快速检查

测试您对处理程序的理解。

回顾

您构建了自定义授权:

  • IAuthorizationRequirement 保存规则数据。
  • AuthorizationHandler<T> 包含逻辑并调用 Succeed。
  • 将处理程序注册为 IAuthorizationHandler,并将要求附加到策略。
  • 基于资源的处理程序和 IAuthorizationService 可以针对特定实例执行授权。

授权课程到此完成。

常见问题解答

「自定义授权要求」课时是免费的吗?

是的 — 「自定义授权要求」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。

「自定义授权要求」这节课中我会学到什么?

构建自定义要求和处理程序。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C# Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「自定义授权要求」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C# Academy 课中编写并运行代码吗?

能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 基于角色的授权
  2. 基于声明的授权
  3. 基于策略的授权
  4. 自定义授权要求
← 返回 C# Academy