从 ASP.NET Core 中的不同 HTTP 标头读取 JWT 令牌
Posted
技术标签:
【中文标题】从 ASP.NET Core 中的不同 HTTP 标头读取 JWT 令牌【英文标题】:Read JWT token from different HTTP header in ASP.NET Core 【发布时间】:2021-10-27 17:33:16 【问题描述】:在 ASP.NET Core API 项目中,我需要验证位于不同于 Authorization 标头的标头中的另一个 JWT Bearer 令牌。例如,假设发送一个 GET 请求以将产品发送到 /api/products
,并在名为 AccessToken
的标头中使用 Bearer 令牌。
curl --location --request GET 'https://localhost/api/products' \
--header 'AccessToken: <bearer_token>'
我正在引用 Microsoft.AspNetCore.Authentication.JwtBearer 包并在 API 项目中设置身份验证,如下所示:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => Configuration.Bind("JwtSettings", options));
但是,我在 JwtBearerOptions Class 中找不到任何有关标题名称的信息。
如何配置 JWT 身份验证以从名为“AccessToken”的标头中读取 JWT? 甚至可以使用 Microsoft.AspNetCore.Authentication.JwtBearer 包吗?
【问题讨论】:
根据来源:github.com/dotnet/aspnetcore/blob/…,此中间件只会查看 auth 标头。如果您想做其他事情,则需要自己编写该中间件。 你必须在你的启动中编写一个自定义中间件。 【参考方案1】:解决方案似乎是使用JwtBearerEvents class。其中有一个委托property named OnMessageReceived ,它“在第一次收到协议消息时调用”。委托将传递MessageReceivedContext 类型的对象,其中有一个名为Token 的属性according to the documentation “这将使应用程序有机会从其他位置检索令牌”。
创建一个继承自 JwtBearerEvents 的类,并在 OnMessageReceived 事件中将上下文对象中的令牌设置为标头“AccessToken”中的值。
/// <summary>
/// Singleton class handler of events related to JWT authentication
/// </summary>
public class AuthEventsHandler : JwtBearerEvents
private const string BearerPrefix = "Bearer ";
private AuthEventsHandler() => OnMessageReceived = MessageReceivedHandler;
/// <summary>
/// Gets single available instance of <see cref="AuthEventsHandler"/>
/// </summary>
public static AuthEventsHandler Instance get; = new AuthEventsHandler();
private Task MessageReceivedHandler(MessageReceivedContext context)
if (context.Request.Headers.TryGetValue("AccessToken", out StringValues headerValue))
string token = headerValue;
if (!string.IsNullOrEmpty(token) && token.StartsWith(BearerPrefix))
token = token.Substring(BearerPrefix.Length);
context.Token = token;
return Task.CompletedTask;
最后,在 Startup 类中将 events 类添加到 JWT 身份验证中。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
Configuration.Bind("JwtSettings", options);
options.Events = AuthEventsHandler.Instance;
);
【讨论】:
这可行,但是如果找不到令牌,处理程序将回退到检查正常的授权标头。这意味着令牌可以在可能不需要的任一标头中发送。为防止这种情况发生,如果找不到令牌,您需要致电context.NoResult()
。如果处理程序看到结果已设置,它将提前返回,而不是继续正常处理。
伙计,你是一个传奇人物——根本没有关于如何使用 JwtBearerEvents 的资源——这对我帮助很大。我将令牌作为表单内容发布,这允许我使用它而不是 auth 标头。
@pinkfloydx33 你是对的,代码缺少一个部分以避免使用 Authorize 标头的默认设置。我完全错过了,很好!以上是关于从 ASP.NET Core 中的不同 HTTP 标头读取 JWT 令牌的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Web API 与 ASP.NET Core 中的 URL 匹配差异
带有 SignalR 集线器的 ASP.NET Core 中的范围服务
ASP.Net Core 6,SPA,端点 - 我无法从 http get 请求调用控制器