validationJWT令牌后访问dotnetcore中间件

我正在使用JWT承载认证,配置如下。

我的问题是在validation令牌之前中间件正在执行。
如何配置中间件以后运行?

services.AddAuthentication() .AddCookie(_ => _.SlidingExpiration = true) .AddJwtBearer( _ => { _.Events = new JwtBearerEvents { // THIS CODE EXECUTES AFTER THE MIDDLEWARE???? OnTokenValidated = context => { context.Principal = new ClaimsPrincipal( new ClaimsIdentity(context.Principal.Claims, "local")); return Task.CompletedTask; } }; _.RequireHttpsMetadata = false; _.SaveToken = false; _.TokenValidationParameters = new TokenValidationParameters() { ValidIssuer = this.Configuration["Tokens:Issuer"], ValidAudience = this.Configuration["Tokens:Issuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this.Configuration["Tokens:Key"])), }; }); 

我试图将中间件添加到访问当前用户的管道中。 遗憾的是,此代码在validation令牌之前执行。 之后如何让它执行?

 public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseIdentityServer(); app.UseAuthentication(); app.Use(async (httpContext, next) => { // THIS CODE EXECUTES BEFORE THE TOKEN IS VALIDATED IN OnTokenValidated. var userName = httpContext.User.Identity.IsAuthenticated ? httpContext.User.GetClaim("email") : "(unknown)"; LogContext.PushProperty("ActiveUser", !string.IsNullOrWhiteSpace(userName) ? userName : "(unknown)"); await next.Invoke(); }); 

看起来你已经找到了解决问题的好方法,但我想我会添加一个答案来解释你所看到的行为。

由于您注册了多个身份validation方案,并且没有一个是默认方案,因此当请求通过管道时,身份validation不会自动发生。 这就是HttpContext.User在通过您的自定义中间件时为空/未经身份validation的原因。 在这种“被动”模式中,在请求之前不会调用认证方案。 在您的示例中,当请求通过AuthorizeFilter时会发生这种情况。 这将触发JWT身份validation处理程序,该处理程序validation令牌,validation和设置身份等。这就是为什么( 如在您的其他问题中 ) User在到达您的控制器操作时正确填充的原因。

它可能对您的场景没有意义(因为您同时使用cookie和jwt)…但是,如果您确实希望Jwt身份validation自动发生,请为管道中的其他中间件设置HttpContext.User ,配置身份validation时需要将其注册为默认方案:

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 

根据@ leppie的评论,这是一个有效的解决方案。

 public class ActiveUserFilter : IAsyncActionFilter { public async Task OnActionExecutionAsync( ActionExecutingContext context, ActionExecutionDelegate next) { var userName = context.HttpContext.User.Identity.IsAuthenticated ? context.HttpContext.User.GetClaim("email") : "(unknown)"; using (LogContext.PushProperty("ActiveUser", !string.IsNullOrWhiteSpace(userName) ? userName : "(unknown)")) await next(); } } 

插入如下……

 services.AddMvc( _ => { _.Filters.Add( new AuthorizeFilter( new AuthorizationPolicyBuilder( JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme) .RequireAuthenticatedUser() .Build())); _.Filters.Add(new ActiveUserFilter()); ...