JWT 承载身份验证不从标头读取令牌

joh*_*y 5 3 c# jwt bearer-token .net-core asp.net-core

我正在尝试使用 .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");
    });
Run Code Online (Sandbox Code Playgroud)

我正在使用我的 access_token 从邮递员发出简单的获取请求:

获取https://localhost:44377/api/values 标头:授权:承载

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

OnMessageReceived = async (ctx) =>
{
    Console.WriteLine(ctx.Token);
}
Run Code Online (Sandbox Code Playgroud)

Kir*_*kin 5

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"];

            ...
Run Code Online (Sandbox Code Playgroud)

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