Asp.Net Core中的帐户角色框架(5)

上一篇分析了权限检验的过程,但感觉还没有分析透彻,今天继续:

IPolicyEvaluator的默认实现类PolicyEvaluator,它有两个方法:

1、AuthenticateAsync,判断身份

2、AuthorizeAsync,判断权限

A、PolicyEvaluator.AuthenticateAsync

研究AuthenticateAsync,通过它的方法定义(如下),可以判断出,身份信息在哪里,在HttpContext中。

public virtual async Task<AuthenticateResult> AuthenticateAsync(AuthorizationPolicy policy, HttpContext context)

继续看代码如下,在context中调用AuthenticateAsync,它是HttpContext的一个扩展方法,定义在AuthenticationHttpContextExtensions中。

var result = await context.AuthenticateAsync(scheme);

B、HttpContext.AuthenticateAsync(位于AuthenticationHttpContextExtensions)

继续查看代码如下,可以看到它通过获取IAuthenticationService的实现类来执行AuthenticateAsync方法。IAuthenticationService默认实现类是AuthenticationService(位于Http文件夹下)

GetAuthenticationService(context).AuthenticateAsync(context, scheme);

private static IAuthenticationService GetAuthenticationService(HttpContext context) =>
        context.RequestServices.GetService<IAuthenticationService>()

C、AuthenticationService(位于Http文件夹下)

AuthenticationService,它的构造函数如下,使用了IAuthenticationHandlerProvider类

public AuthenticationService(IAuthenticationSchemeProvider schemes, IAuthenticationHandlerProvider handlers, IClaimsTransformation transform, IOptions<AuthenticationOptions> options)

继续深挖,看AuthenticateAsync方法,关键代码如下,通过IAuthenticationHandlerProvider获得IAuthenticationHandler,之后执行其AuthenticateAsync,获得身份验证结果。

IAuthenticationHandlerProvider的默认实现类是AuthenticationHandlerProvider。

IAuthenticationHandler有很多实现类,其中CookieAuthenticationHandler是Cookie身份验证方案的默认实现类

var handler = await Handlers.GetHandlerAsync(context, scheme);

var result = (await handler.AuthenticateAsync()) ?? AuthenticateResult.NoResult();

D、AuthenticationHandlerProvider.GetHandlerAsync(位于Http文件夹下)

这里个关键代码如下,获取对应Handler的实例;如果没有,则创建一个新的。

var handler = (context.RequestServices.GetService(scheme.HandlerType) ??
            ActivatorUtilities.CreateInstance(context.RequestServices, scheme.HandlerType))
            as IAuthenticationHandler;

E、CookieAuthenticationHandler,位于Cookie文件夹下

这里就基于Cookie来验证身份。

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var result = await EnsureCookieTicket();
        if (!result.Succeeded)
        {
            return result;
        }

        // We check this before the ValidatePrincipal event because we want to make sure we capture a clean clone
        // without picking up any per-request modifications to the principal.
        await CheckForRefreshAsync(result.Ticket);

        Debug.Assert(result.Ticket != null);
        var context = new CookieValidatePrincipalContext(Context, Scheme, Options, result.Ticket);
        await Events.ValidatePrincipal(context);

        if (context.Principal == null)
        {
            return AuthenticateResult.Fail("No principal.");
        }

        if (context.ShouldRenew)
        {
            RequestRefresh(result.Ticket, context.Principal);
        }

        return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));
    }

所以,如果要创建一套新的身份验证方案,那么对应的是

1、首先必须是基于Web的,身份信息将存储在HttpContext中

2、实现IAuthenticationHandler接口,处理多个场景

其他则看具体身份验证要求来实现。

梳理完之后,可以发现,PolicyEvaluator.AuthenticateAsyncAuthenticationMiddleware.Invoke,在功能上来说,是几乎一致的。