Vac*_*ano 8 c# .net-core asp.net-core asp.net-core-3.1
我使用 WSO2 作为我的身份提供者 (IDP)。它将 JWT 放在名为“X-JWT-Assertion”的标头中。
为了将其提供给 ASP.NET Core 系统,我添加了一个OnMessageReceived事件。这允许我将 设置token为标题中提供的值。
这是我必须执行的代码(关键部分是非括号代码的最后 3 行):
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddJwtBearer(async options =>
{
options.TokenValidationParameters =
await wso2Actions.JwtOperations.GetTokenValidationParameters();
options.Events = new JwtBearerEvents()
{
// WSO2 sends the JWT in a different field than what is expected.
// This allows us to feed it in.
OnMessageReceived = context =>
{
context.Token = context.HttpContext.Request.Headers["X-JWT-Assertion"];
return Task.CompletedTask;
}
}
};
Run Code Online (Sandbox Code Playgroud)
除了服务启动后的第一次调用外,这一切都完美无缺。需要明确的是,除了第一个调用之外,每个调用都完全按照我的意愿工作。(它把令牌放入并更新User我需要的对象。)
但是对于第一次调用,OnMessageReceived没有命中。并且User我的控制器中的对象没有设置。
我检查HttpContext了第一个调用,并且“X-JWT-Assertion”标头在Request.Headers列表中(其中包含 JWT)。但是,出于某种原因,该OnMessageReceived事件并没有被要求。
如何OnMessageReceived在第一次调用我的服务的服务操作时被调用?
重要提示:我发现问题出async await在AddJwtBearer. (见下面我的回答。)这就是我真正想从这个问题中得到的。
然而,由于赏金不能cancled,我仍然会奖励赏金的人谁可以显示的方式,使用AddJwtBearer与async await它正在等待一个实际的HttpClient通话。或显示为什么async await不应该与AddJwtBearer.
更新:
lambda 是一种Action方法。它不返回任何东西。因此,尝试在其中实现异步是不可能的,除非它被火和遗忘。
此外,该方法在第一次调用时被调用。所以答案是提前在这个方法中调用你需要的任何东西并缓存它。(但是,我还没有想出一种使用依赖注入项进行此调用的非 hack 方法。)然后在第一次调用期间,将调用此 lambda。那时你应该从缓存中提取你需要的值(因此不会减慢第一次调用的速度)。
这是我最后想出来的。
lambda forAddJwtBearer不适用于async await. 我的呼叫await wso2Actions.JwtOperations.GetTokenValidationParameters();等待很好,但呼叫管道继续进行而无需等待AddJwtBearer完成。
随着async await呼叫顺序是这样的:
AddJwtBearer 叫做。await wso2Actions.JwtOperations.GetTokenValidationParameters(); 叫做。GetTokenValidationParameters()调用HttpClientwith await。HttpClient做一个期待已久的调用来获取发行人的公开签名密钥。HttpClient等待时,原始调用的其余部分会通过。尚未设置任何事件,因此它只是像往常一样继续调用管道。
OnMessageReceived事件的地方。HttpClient获取与公共密钥的响应。AddJwtBearer继续。OnMessageReceived事件是设置。AddJwtBearer仅在第一次调用时调用。)因此,当等待发生时(在这种情况下,它最终会调用 HttpClient 以获取颁发者签名密钥),第一个调用的其余部分会通过。因为还没有事件设置,它不知道调用处理程序。
我将 lambda 更改AddJwtBearer为不是异步的,它工作得很好。
注意:
这里有两件事看起来很奇怪:
AddJwtBearer会在启动时调用,而不是在第一次调用服务时调用。AddJwtBearer不支持asynclambda 签名。我不确定这是否是一个错误,但我将其作为一个发布以防万一:https : //github.com/dotnet/aspnetcore/issues/20799
| 归档时间: |
|
| 查看次数: |
2690 次 |
| 最近记录: |