I've been on quite an adventure to get JWT working on DotNet core 2.0 (now reaching final release today). There is a ton of documentation, but all the sample code seems to be using deprecated APIs and coming in fresh to Core, It's positively dizzying to figure out how exactly it's supposed to be implemented. I tried using Jose, but app. UseJwtBearerAuthentication has been deprecated, and there is no documentation on what to do next.
Does anyone have an open source project that uses dotnet core 2.0 that can simply parse a JWT from the authorization header and allow me to authorize requests for a HS256 encoded JWT token?
The class below doesn't throw any exceptions, but no requests are authorized, and I get no indication why they are unauthorized. The responses are empty 401's, so to me that indicates there was no exception, but that the secret isn't matching.
One odd thing is that my tokens are encrypted with the HS256 algorithm, but I see no indicator to tell it to force it to use that algorithm anywhere.
Here is the class I have so far:
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json.Linq;
using Microsoft.IdentityModel.Tokens;
using System.Text;
namespace Site.Authorization
{
public static class SiteAuthorizationExtensions
{
public static IServiceCollection AddSiteAuthorization(this IServiceCollection services)
{
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("SECRET_KEY"));
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
ValidateAudience = false,
ValidateIssuer = false,
IssuerSigningKeys = new List<SecurityKey>{ signingKey },
// Validate the token expiry
ValidateLifetime = true,
};
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.IncludeErrorDetails = true;
o.TokenValidationParameters = tokenValidationParameters;
o.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = c =>
{
c.NoResult();
c.Response.StatusCode = 401;
c.Response.ContentType = "text/plain";
return c.Response.WriteAsync(c.Exception.ToString());
}
};
});
return services;
}
}
}