我们知道我们可以使用多种方案来验证用户,例如
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
扩展方法时,我们将处理程序类型的scheme添加为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
是如何处理多个方案并调用多个处理程序的呢?据我所知,只应用了默认方案?
2条答案
按热度按时间daupos2t1#
AuthenticationMiddleware如何处理多个方案并调用多个处理程序?
不会的正如你提到的,
AuthenticationMiddleware
只对默认方案进行身份验证。如果你有多个身份验证方案,你需要使用AuthorizationMiddleware
和Policy
。你可以设置策略必须使用的身份验证方案并将其应用于端点。然后AuthorizationMiddleware
将使用指定的方案对该端点进行身份验证。hyrbngr72#
**注意:**这个答案是基于我对ASP.NET Core 7.0.13的程序集和源代码的阅读-它不适用于ASP.NET Core的早期版本,如1.x,2.x和3.x(甚至可能是5.x甚至6.x),其中authX系统设计经历了频繁的重新设计和迭代。
在答复任择议定书的后续问题时:
好的,你能给我看看
AuthenticationMiddleware
源代码吗?哪个代码块调用了多个IAuthenticationHandler
。答案是“它不会”(基本上是the same as what @Kahbazi says in his answer),但这必然会让我们问 “那么,当您指定多个身份验证方案时,
[Authorize]
是如何工作的?"...这个问题的答案在于 * 另一个中间件 *,因为(令人惊讶的是),
AuthenticationMiddleware
并不是唯一执行请求身份验证的中间件。要点1:您将有一个隐式或显式的
AuthorizationPolicy
:当您有一个列出了多个方案的
[Authorize]
属性(如[Authorize( AuthenticationSchemes = "MyCookieScheme, MyJwtScheme, MyHttpBasicScheme" )]
)时,ASP.NET将隐式地将该属性转换为AuthorizationPolicy
(通过interface IAuthorizeData
),每个方案都列在该策略的.AuthenticationSchemes
字符串集合中。在另一种情况下,如果您直接专门配置
AuthorizationPolicy
(而不使用[Authorize]
),那么您也可以在.AuthenticationSchemes
中设置多个方案名称。要点2:
AuthorizationPolicy
实际上是由不同的中间件进行评估的,而不是由AuthenticationMiddleware
进行评估的..
.所以反直觉,_当你使用2个或更多的身份验证方案,然后
AuthorizationMiddleware
将执行双重职责,也验证请求除了授权他们.就在这里:https://github.com/dotnet/aspnetcore/blob/ae33890a62edb2fed5554efab597fb7fc41f8cbe/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs#L156C9-L156C9
字符串
foreach
循环遍历所有列出的AuthenticationSchemes
is inclass PolicyEvaluator : IPolicyEvaluator
:型