IAuthorizationHandlerProvider的默认实现为DefaultAuthorizationHandlerProvider:
public class DefaultAuthorizationHandlerProvider : IAuthorizationHandlerProvider { private readonly IEnumerable<IAuthorizationHandler> _handlers; public DefaultAuthorizationHandlerProvider(IEnumerable<IAuthorizationHandler> handlers) { _handlers = handlers; } public Task<IEnumerable<IAuthorizationHandler>> GetHandlersAsync(AuthorizationHandlerContext context) => Task.FromResult(_handlers); }在《上一章》中,我们还介绍到,我们定义的Requirement,可以直接实现IAuthorizationHandler接口,也可以单独定义Handler,但是需要注册到DI系统中去。
在默认的AuthorizationHandlerProvider中,会从DI系统中获取到我们注册的所有Handler,最终调用其HandleAsync方法。
我们在实现IAuthorizationHandler接口时,通常是继承自AuthorizationHandler<TRequirement>来实现,它有如下定义:
public abstract class AuthorizationHandler<TRequirement> : IAuthorizationHandler where TRequirement : IAuthorizationRequirement { public virtual async Task HandleAsync(AuthorizationHandlerContext context) { foreach (var req in context.Requirements.OfType<TRequirement>()) { await HandleRequirementAsync(context, req); } } protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement); }如上,首先会在HandleAsync过滤出与Requirement对匹配的Handler,然后再调用其HandleRequirementAsync方法。
那我们定义的直接实现IAuthorizationHandler了接口的Requirement又是如何执行的呢?
在AddAuthorization扩展方法中可以看到,默认还为IAuthorizationHandler注册了一个PassThroughAuthorizationHandler,定义如下:
public class PassThroughAuthorizationHandler : IAuthorizationHandler { public async Task HandleAsync(AuthorizationHandlerContext context) { foreach (var handler in context.Requirements.OfType<IAuthorizationHandler>()) { await handler.HandleAsync(context); } } }它负责调用该策略中所有实现了IAuthorizationHandler接口的Requirement。
IAuthorizationEvaluator最后,通过调用IAuthorizationEvaluator接口,来完成最终的授权结果,默认实现为DefaultAuthorizationEvaluator:
public class DefaultAuthorizationEvaluator : IAuthorizationEvaluator { public AuthorizationResult Evaluate(AuthorizationHandlerContext context) => context.HasSucceeded ? AuthorizationResult.Success() : AuthorizationResult.Failed(context.HasFailed ? AuthorizationFailure.ExplicitFail() : AuthorizationFailure.Failed(context.PendingRequirements)); }当我们在一个策略中指定多个Requirement时,只有全部验证通过时,授权上下文中的HasSucceeded才会为True,而HasFailed代表授权结果的显式失败。
这里根据授权上下文的验证结果来生成授权结果:
public class AuthorizationResult { public bool Succeeded { get; private set; } public AuthorizationFailure Failure { get; private set; } public static AuthorizationResult Success() => new AuthorizationResult { Succeeded = true }; public static AuthorizationResult Failed(AuthorizationFailure failure) => new AuthorizationResult { Failure = failure }; public static AuthorizationResult Failed() => new AuthorizationResult { Failure = AuthorizationFailure.ExplicitFail() }; } public class AuthorizationFailure { private AuthorizationFailure() { } public bool FailCalled { get; private set; } public IEnumerable<IAuthorizationRequirement> FailedRequirements { get; private set; } public static AuthorizationFailure ExplicitFail() { return new AuthorizationFailure { FailCalled = true, FailedRequirements = new IAuthorizationRequirement[0] }; } public static AuthorizationFailure Failed(IEnumerable<IAuthorizationRequirement> failed) => new AuthorizationFailure { FailedRequirements = failed }; }整个授权流程的结构大致如下:
总结