Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JWT Bearer Authentication Does not read Token from headers

I'm trying to authenticate with JWT Bearer in .Net-Core, here is my startup:

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");
    });

I'm making a simple Get Request From Postman using my access_token:

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

However when I inspect the tokens on message received I'm always getting null

OnMessageReceived = async (ctx) =>
{
    Console.WriteLine(ctx.Token);
}
like image 881
johnny 5 Avatar asked Oct 12 '25 17:10

johnny 5


1 Answers

The OnMessageReceived delegate is called without first setting the Token property. For this event, Token is something you can set yourself if you're overriding how the token is retrieved. You can see this for yourself in the 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"];

            ...

The call to Events.MessageReceived invokes your OnMessageReceived delegate, but the MessageReceivedContext hasn't been initialised with a Token, so it's just null. After the call to Events.MessageReceived, the token is retrieved from the Authorization header (if you haven't set it yourself as I mentioned).

like image 109
Craig Avatar answered Oct 14 '25 10:10

Craig