JWT Bearer Authentication 不从标头中读取 Token

Posted

技术标签:

【中文标题】JWT Bearer Authentication 不从标头中读取 Token【英文标题】:JWT Bearer Authentication Does not read Token from headers 【发布时间】:2019-06-27 01:19:49 【问题描述】:

我正在尝试使用 .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:

获取https://localhost:44377/api/values HEADERS: 授权: Bearer

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

OnMessageReceived = async (ctx) =>

    Console.WriteLine(ctx.Token);

【问题讨论】:

【参考方案1】:

调用OnMessageReceived 委托时无需先设置Token 属性。对于这个事件,Token 是您可以设置自己的东西,如果您要覆盖令牌的检索方式。你可以在source code看到这个:

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 尚未使用Token 进行初始化,所以它只是null。在调用Events.MessageReceived 之后,会从Authorization 标头中检索令牌(如果您没有按照我提到的那样自己设置)。

【讨论】:

以上是关于JWT Bearer Authentication 不从标头中读取 Token的主要内容,如果未能解决你的问题,请参考以下文章

Jwt Bearer Authentication 中间件始终将 User.Identity.IsAuthenticated 设置为 false

将 JWT Bearer Authentication Web API 与 Asp.Net Core 2.0 结合使用的问题

JWT Bearer ASP.Net Core 3.1 用户在服务器上为空白

AspNetCore 2.1 Bearer Token Authentication - 当前用户为空

JWT 为啥我们需要 Bearer word?

在 React 项目中,我应该在哪里传递 Bearer Authentication Token?