如何使用 OWIN Jwt Bearer Authentication 记录身份验证结果

Posted

技术标签:

【中文标题】如何使用 OWIN Jwt Bearer Authentication 记录身份验证结果【英文标题】:How to log authentication result with OWIN Jwt Bearer Authentication 【发布时间】:2018-07-10 08:27:53 【问题描述】:

我想记录对我的 .netcore webapi 的所有调用的统计信息。

为此,我添加了一个IAsyncActionFilter,它会处理所有操作。

但我也启用了 Jwt Bearer 身份验证,并在我的控制器上使用 AuthorizeAttribute 来限制访问。当访问被拒绝时,将不会点击操作过滤器。

添加一些自定义日志记录 (statsd) 以进行一般身份验证和特别是失败的最佳方式是什么?

public void ConfigureServices(IServiceCollection services)

....
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        
            // base-address of your identityserver
            options.Authority = Configuration["Authority"]; ;

            // name of the API resource
            options.Audience = "myAudience";
        );
...


public void Configure(IApplicationBuilder app, IHostingEnvironment env)

...
    app.UseAuthentication();
...

我注意到 JwtBearerOptionsJwtBearerEvents Events 但我无法让它工作。

编辑:看起来我在没有令牌的情况下访问 api,JWT Auth 处理程序返回 AuthenticateResult.NoResult() 而不调用 Events.AuthenticationFailed

https://github.com/aspnet/Security/blob/ba1eb281d135400436c52c17edc71307bc038ec0/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs#L63-L83

编辑 2:非常令人沮丧。看起来正确的登录位置应该是Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter 但是当您使用[Authorize] 时会自动添加,并且无法覆盖、删除或替换?

【问题讨论】:

【参考方案1】:

我对 Jwt Bearer 身份验证没有任何经验 - 但我们也遇到过类似情况。我们最终得到了一个新的 BaseController,我们可以在其中记录基本用户信息并区分 [AllowAnonymous][Authorize]

public class NewBaseController : Controller

    protected UserManager<MyUser> UserManager;
    protected MyUser CurrentUser;
    protected ILogger Logger;

    public override void OnActionExecuting(ActionExecutingContext context)
    
        base.OnActionExecuting(context);

        UserManager = context.HttpContext.RequestServices.GetService<UserManager<MyUser>>();

        var loggerFactory = context.HttpContext.RequestServices.GetService<ILoggerFactory>();
        Logger = loggerFactory.CreateLogger(GetType());
        // Check if Action is annotated with [AllowAnonymous]
        var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        var anonymousAllowed = controllerActionDescriptor.MethodInfo
            .GetCustomAttributes(inherit: true)
            .Any(a => a.GetType().Equals(typeof(AllowAnonymousAttribute)));

        if (!anonymousAllowed)
        
            ApplicationUser = UserManager.GetUserAsync(User).Result;
            if (ApplicationUser == null)
                // do some stuff
            Logger.LogInformation("User is UserId", CurrentUser.Id);
        
        else
        
            Logger.LogInformation("User is User", anonymous);
        
    
 

奖励:从这个基础派生的每个控制器都已经有一个 UserManager、ILogger 和 CurrentUser 的实例。

希望接近您正在寻找的...

【讨论】:

嗨。我试了一下,但看起来控制器 OnActionExecuting 没有被称为 AuthorizeAttribute 中的身份验证过滤器首先被击中? ps。我不确定它是否相关,但我的 [Authorize] 在控制器上 pps。不,我移动了它,它仍然没有运行 好的..值得一试,我认为 :) 正如我所提到的,我不确定它是否适用于 Jwt.. 希望你能找到你的解决方案【参考方案2】:

JwtBearerOptions.cs 类公开了一个 JwtBearerEvents 参数,您可以在其中声明这样的事件

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    
        // base-address of your identityserver
        options.Authority = Configuration["Authority"]; ;

        // name of the API resource
        options.Audience = "myAudience";

        options.Events = new JwtBearerEvents
        
            OnAuthenticationFailed = context =>
            
                //Log failed authentications
                return Task.CompletedTask;
            ,
            OnTokenValidated = context =>
            
                //Log successful authentications
                return Task.CompletedTask;
            
        ;

    );

【讨论】:

是的,我做到了。没有令牌时它不会调用 OnAuthenticationFailed @Ewan 你是正确的。如果在 HTTP 请求中找不到令牌,JWT 中间件不会做任何事情。我认为这就是你想要的,记录失败的身份验证。好的,如果您想记录所有请求,请在身份验证中间件之前添加一个日志记录 mddleware 嗯,这就是我的想法引导我的地方。我想如果我将过滤器更改为中间件并将其放在第一位,我将能够以某种方式检测到失败或成功的身份验证? 奇怪的是它必须是授权属性的授权处理程序,它会终止请求,并且不清楚它适合中间件的位置。 也适用于 .net core 3。非常感谢!

以上是关于如何使用 OWIN Jwt Bearer Authentication 记录身份验证结果的主要内容,如果未能解决你的问题,请参考以下文章

Auth0 - 在 Owin 上使用带有承载访问令牌的 JWT 使用 RS256 进行身份验证

ASP.net Core 2.0 AzureAd Bearer JWT-Token Auth 在验证签名时不会失败

通过 AWS EC2 上的 Docker 容器发布时,Auth0 OWIN API 未验证 JWT 令牌

JWT 为啥我们需要 Bearer word?

NextAuth jwt 作为 header.Authorization Bearer Token Next Js

Owin Web API Bearer Token 直通