从 ASP.NET 核心中的不同 HTTP header 读取 JWT 令牌
Read JWT token from different HTTP header in ASP.NET Core
在 ASP.NET 核心 API 项目中,我需要验证位于 header 中不同于授权 header 的另一个 JWT Bearer 令牌。例如,假设发送一个 GET 请求以将产品发送到 /api/products
,并在名为 AccessToken
.
的 header 中使用不记名令牌
curl --location --request GET 'https://localhost/api/products' \
--header 'AccessToken: <bearer_token>'
我在 API 项目中引用 Microsoft.AspNetCore.Authentication.JwtBearer 包并设置身份验证,如下所示:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => Configuration.Bind("JwtSettings", options));
但是,我在 JwtBearerOptions Class.
中找不到任何关于 header 名称的信息
如何配置 JWT 身份验证以从名为“AccessToken”的 header 读取 JWT?
甚至可以使用 Microsoft.AspNetCore.Authentication.JwtBearer 包吗?
解决方案似乎是使用 JwtBearerEvents class. In it, there's a delegate property named OnMessageReceived that it's "invoked when a protocol message is first received". The delegate will pass a object of type of MessageReceivedContext, where it has a property named Token that according to the documentation “这将使应用程序有机会从其他位置检索令牌”。
创建一个继承自 JwtBearerEvents 的 class,并在 OnMessageReceived 事件中将上下文 object 中的令牌设置为 header“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;
}
}
最后,将事件 class 添加到启动时的 JWT 身份验证 class。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
Configuration.Bind("JwtSettings", options);
options.Events = AuthEventsHandler.Instance;
});
在 ASP.NET 核心 API 项目中,我需要验证位于 header 中不同于授权 header 的另一个 JWT Bearer 令牌。例如,假设发送一个 GET 请求以将产品发送到 /api/products
,并在名为 AccessToken
.
curl --location --request GET 'https://localhost/api/products' \
--header 'AccessToken: <bearer_token>'
我在 API 项目中引用 Microsoft.AspNetCore.Authentication.JwtBearer 包并设置身份验证,如下所示:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => Configuration.Bind("JwtSettings", options));
但是,我在 JwtBearerOptions Class.
中找不到任何关于 header 名称的信息如何配置 JWT 身份验证以从名为“AccessToken”的 header 读取 JWT? 甚至可以使用 Microsoft.AspNetCore.Authentication.JwtBearer 包吗?
解决方案似乎是使用 JwtBearerEvents class. In it, there's a delegate property named OnMessageReceived that it's "invoked when a protocol message is first received". The delegate will pass a object of type of MessageReceivedContext, where it has a property named Token that according to the documentation “这将使应用程序有机会从其他位置检索令牌”。
创建一个继承自 JwtBearerEvents 的 class,并在 OnMessageReceived 事件中将上下文 object 中的令牌设置为 header“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;
}
}
最后,将事件 class 添加到启动时的 JWT 身份验证 class。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
Configuration.Bind("JwtSettings", options);
options.Events = AuthEventsHandler.Instance;
});