我们知道我们可以使用多种方案对用户进行身份验证,例如
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,
options => builder.Configuration.Bind("JwtSettings", options))
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
options => builder.Configuration.Bind("CookieSettings", options));
但根据AuthenticationMiddleware
代码:
https://source.dot.net/#Microsoft.AspNetCore.Authentication/AuthenticationMiddleware.cs,50个
public async Task Invoke(HttpContext context)
{
// ...
var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
{
var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler;
if (handler != null && await handler.HandleRequestAsync())
{
return;
}
}
var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
if (defaultAuthenticate != null)
{
var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
// ...
}
await _next(context);
}
foreach
人似乎从一开始就采用了多种方案.然而,它使用的是IAuthenticationRequestHandler
,而不是IAuthenticationHandler
.
因此,当我们调用AddCookie
扩展方法时,我们将处理程序类型的方案添加为CookieAuthenticationHandler
(https://source.dot.net/#Microsoft.AspNetCore.Authentication.Cookies/CookieExtensions.cs,81)
接口实现链为:
public class CookieAuthenticationHandler : SignInAuthenticationHandler<CookieAuthenticationOptions>
public abstract class SignInAuthenticationHandler<TOptions> : SignOutAuthenticationHandler<TOptions>, IAuthenticationSignInHandler
// ...
如果我们一直向上跟踪,SignInAuthenticationHandler
就不会实现IAuthenticationRequestHandler
,那么AuthenticationMiddleware
如何处理多个方案和调用多个处理程序呢?据我所知,只有默认方案才适用吗?