首页 > 解决方案 > JWT Bearer Authentication 不从标头中读取 Token

问题描述

我正在尝试使用 .Net-Core 中的 JWT Bearer 进行身份验证,这是我的启动:

var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));

// Configure JwtIssuerOptions
services.Configure<JwtIssuerOptions>(options =>
{
    options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
    options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
    options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
});

var tokenValidationParameters = new TokenValidationParameters
{
    ValidateIssuer = true,
    ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],

    ValidateAudience = true,
    ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],

    ValidateIssuerSigningKey = true,
    IssuerSigningKey = _signingKey,

    RequireExpirationTime = false,
    ValidateLifetime = true,
    ClockSkew = TimeSpan.Zero
};

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(cfg =>
    {
        cfg.RequireHttpsMetadata = false;
        cfg.SaveToken = true;

        cfg.Events = new JwtBearerEvents
        {
            OnMessageReceived = async (ctx) =>
            {
                Console.WriteLine(ctx.Token);
            },

            OnTokenValidated = async (ctx) =>
            {
                Console.WriteLine("BreakPoint");
            },
        };

        cfg.TokenValidationParameters = tokenValidationParameters;
    })
    .AddCoinbase(options => {
        options.AccessAllAccounts = true;
        options.SendLimitAmount = 1;
        options.SendLimitCurrency = "USD";
        options.SendLimitPeriod = SendLimitPeriod.day;
        options.ClientId = Configuration["Coinbase:ClientId"];
        options.ClientSecret = Configuration["Coinbase:ClientSecret"];
        COINBASE_SCOPES.ForEach(scope => options.Scope.Add(scope));
        options.SaveTokens = true;
        options.ClaimActions.MapJsonKey("urn:coinbase:avatar", "avatar_url");
    });

我正在使用我的 access_token 从 Postman 发出一个简单的 Get Request:

GET https://localhost:44377/api/values HEADERS: Authorization: Bearer

但是,当我检查收到的消息上的令牌时,我总是得到 null

OnMessageReceived = async (ctx) =>
{
    Console.WriteLine(ctx.Token);
}

标签: c#asp.net-core.net-corejwtbearer-token

解决方案


在没有首先设置属性OnMessageReceived的情况下调用委托。Token对于此事件,Token如果您要覆盖令牌的检索方式,您可以自行设置。您可以在源代码中自己查看:

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    string token = null;
    try
    {
        // Give application opportunity to find from a different location, adjust, or reject token
        var messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options);

        // event can set the token
        await Events.MessageReceived(messageReceivedContext);
        if (messageReceivedContext.Result != null)
        {
            return messageReceivedContext.Result;
        }

        // If application retrieved token from somewhere else, use that.
        token = messageReceivedContext.Token;

        if (string.IsNullOrEmpty(token))
        {
            string authorization = Request.Headers["Authorization"];

            ...

调用Events.MessageReceived调用您的OnMessageReceived委托,但MessageReceivedContext尚未使用 a 初始化Token,所以它只是null. 在调用 之后Events.MessageReceived,会从Authorization标头中检索令牌(如果您没有像我提到的那样自己设置它)。


推荐阅读