问题描述
我正在使用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中间件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!