本文介绍了在验证 JWT 令牌后访问 dotnetcore 中间件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是JWT承载认证,配置如下.

I am using JWT bearer authentication, configured as follows.

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

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"])),
            };
        });

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

I am attempting to add middleware into the pipeline that accesses the current user. This code unfortunately executes BEFORE the token is validated. How do I make it execute afterwards?

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();
       });

推荐答案

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

It looks like you've found a good solution to your problem but I thought I'd add an answer to explain the behavior you're seeing.

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

Since you have multiple authentication schemes registered and none is the default, authentication does not happen automatically as the request goes through the pipeline. That's why the HttpContext.User was empty/unauthenticated when it went through your custom middleware. In this "passive" mode, the authentication scheme won't be invoked until it is requested. In your example, this happens when the request passes through your AuthorizeFilter. This triggers the JWT authentication handler, which validates the token, authenticates and sets the Identity, etc. That's why (as in your other question) the User is populated correctly by the time it gets to your controller action.

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

It probably doesn't make sense for your scenario (since you're using both cookies and jwt)... however, if you did want the Jwt authentication to happen automatically, setting HttpContext.User for other middleware in the pipeline, you just need to register it as the default scheme when configuring authentication:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

这篇关于在验证 JWT 令牌后访问 dotnetcore 中间件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-15 14:04