I believe I have the Microsoft Authentication Library (MSAL) JavaScript pulling back a JWT token, using azure AD multi tenant with the following config. Based of this link https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant. I believe I only need the following two values.
clientId: "A134d6c8-8078-2924-9e90-98cef862eb9a" // this would be the app registrations client id(application)
authority: "https://login.microsoftonline.com/common"
How then can I configure a .net core 3 web api that can handle this JWT token and authenticate [Authorize] endpoints by me passing the Authorization: Bearer header.
I currently get this error in the response which is not very helpful!
AuthenticationFailed: IDX10511: Signature validation failed. Keys tried: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
kid: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
Exceptions caught:
'[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
token: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
The Startup.cs code is as follows
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
namespace MultiTenantApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(x =>
{
x.AddDefaultPolicy(cfg =>
{
cfg.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddAuthentication(cfg =>
{
cfg.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
cfg.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(opt =>
{
opt.Authority = "https://login.microsoftonline.com/common";
opt.Audience = "api://A134d6c8-8078-2924-9e90-98cef862eb9a"; // Set this to the App ID URL for the web API, which you created when you registered the web API with Azure AD.
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false
};
opt.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = AuthenticationFailed
};
});
services.AddControllers();
}
private Task AuthenticationFailed(AuthenticationFailedContext arg)
{
// For debugging purposes only!
var s = $"AuthenticationFailed: {arg.Exception.Message}";
arg.Response.ContentLength = s.Length;
arg.Response.Body.WriteAsync(Encoding.UTF8.GetBytes(s), 0, s.Length);
return Task.FromResult(0);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); // Added
app.UseRouting();
app.UseCors(); //Added
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}