在验证JWT令牌之后访问dotnetcore中间件

Jim*_*Jim 6 c# asp.net-mvc jwt .net-core

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

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

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"])),
            };
        });
Run Code Online (Sandbox Code Playgroud)

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

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();
       });
Run Code Online (Sandbox Code Playgroud)

Pet*_*ter 8

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

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

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

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
Run Code Online (Sandbox Code Playgroud)

  • 我可能会在某些时候丢弃cookie,但希望两者都能正常工作.我没有预见到这些棘手的情景.虽然我的解决方案有效 - 我接受你的答案 - 这是一个很好的解释,肯定会帮助其他工程师解决持票人代币问题. (2认同)