.net core 2.1中具有自定义授权的JwtBearer身份验证

时间:2019-02-04 09:57:12

标签: c# authentication authorization asp.net-core-2.1 asp.net-core-middleware

我们有一个网关(使用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属性中进行修饰。任何人都可以对如何实现相同目标有所了解吗?

非常感谢您的帮助

1 个答案:

答案 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中间件之间,问题已解决