我们有一个网关(使用Ocelot实现),该网关在到达API之前执行呼叫的身份验证和授权
对于身份验证,网关使用如下所示的JwtBearer
services.AddAuthentication(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Events = JwtBeaerEvents();
options.TokenValidationParameters = TokenValidationParameters(tokenConfig);
});
而且,这可以正确验证令牌。
除此之外,网关还通过“自定义授权”实现,它使用自定义配置文件读取与权限相关的设置。而且,此自定义授权已添加为中间件
我们尝试在身份验证中间件之后添加此授权中间件,例如
app.UseAuthentication().UseAuthorizationMiddleware();
这适用于有效令牌。但是,对于无效的令牌,无论身份验证失败如何,该调用也将路由到AuthorizationMiddleware。而且,基于these的发现,看来我们需要使用DI而不是中间件。但是,我们想要的是一个授权的自定义实现,该实现通过配置文件(在网关中)与JwtBearer方案一起接受权限/策略/范围,而不是在API属性中进行修饰。任何人都可以对如何实现相同目标有所了解吗?
非常感谢您的帮助
答案 0 :(得分:0)
该问题归因于.net核心的behaviour。当Identity的IsAuthenticated标志为false时,如果在身份验证期间令牌验证失败的情况下,框架不会将Http StatusCode设置为401,并且它会继续进行下一个调用。如果仅使用基于策略的授权,则在构建授权策略时,RequireAuthenticatedUser()会自动对其进行处理。但是,由于我们使用的是自定义中间件,因此引入了另一个中间件,该中间件可以复制DenyAnonymousAuthorizationRequirement的功能,如下所示
var user = httpContext.User;
var userIsAnonymous =
user?.Identity == null ||
!user.Identities.Any(i => i.IsAuthenticated);
if (userIsAnonymous)
{
httpContext.Response.StatusCode = 401;
return Task.CompletedTask;
}
return _next(httpContext);
我们将此中间件放置在Authentication&Authorization中间件之间,问题已解决