. NET Core API项目中,我需要验证位于与授权标头不同的标头中的另一个JWT承载令牌。例如,想象发送一个GET请求以获取产品到/api/products
,并在标题中使用名为AccessToken
的承载令牌。
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类中找不到任何关于头名称的内容。
如何配置JWT身份验证以从名为"AccessToken"的头中读取JWT ?甚至可以使用Microsoft.AspNetCore.Authentication.JwtBearer包吗?
解决方案似乎是使用JwtBearerEvents类。在它里面,有一个名为onmessagerreceived的委托属性它会在第一次接收到协议消息时被调用。委托将传递一个MessageReceivedContext类型的对象,其中它有一个名为Token的属性,根据文档,这将给应用程序一个从替代位置检索令牌的机会.
创建一个继承JwtBearerEvents的类,并在onmessagerreceived事件中将上下文对象中的令牌设置为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;
}
}
最后,在Startup类中将events类添加到JWT身份验证。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
Configuration.Bind("JwtSettings", options);
options.Events = AuthEventsHandler.Instance;
});