如何使用 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();
...
我注意到 JwtBearerOptions
有 JwtBearerEvents 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 令牌