We have built a microservices application which consists of 3 main services. We needed to have an Api Gateway for routing and mainly for authentication and authorizations purposes as 2 of the 3 services need to have an authenticated user to make the request. The routing works fine but when I try to add the authentication and test it using postman it fails to send the request with a response 401 Unauthorized. Here is what I have done so far:
Ocelot.json
{
"Routes": [
{
"DownstreamPathTemplate": "/api/courses/{everything}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 7123
}
],
"UpstreamPathTemplate": "/api/courses/{everything}",
"UpstreamHttpMethod": [ "POST", "PUT", "GET", "DELETE" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
}
},
{
"DownstreamPathTemplate": "/api/users/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 8080
}
],
"UpstreamPathTemplate": "/api/users/{everything}",
"UpstreamHttpMethod": [ "POST", "PUT", "GET", "DELETE" ]
},
{
"DownstreamPathTemplate": "/api/exam/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 8888
}
],
"UpstreamPathTemplate": "/api/exam/{everything}",
"UpstreamHttpMethod": [ "POST", "PUT", "GET", "DELETE" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
}
}
],
"GlobalConfiguration": {}
}
I thought the service that generates the token could be the problem, so I have generated an online token but still the same issue
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2NTcwMjg2MTcsImV4cCI6MTY1NzQ2MDYxNywic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSJ9.nLAHN2vlpwd4seqCaxuqpBNgYuEeyKUmfoLW0CFsHTI
Program.cs File
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile("Ocelot.dev.json");
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Environment.GetEnvironmentVariable("AUTH_SECRET_KEY", EnvironmentVariableTarget.Process)!)),
ValidateIssuerSigningKey = true,
ValidateIssuer = false,
ValidateAudience = false,
};
});
builder.Services.AddOcelot();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseOcelot().Wait();
app.UseAuthorization();
app.Run();
Secret key im using is "secret"
Error message from console:
warn: Ocelot.Authentication.Middleware.AuthenticationMiddleware[0]
requestId: 0HMIUJ2BDCV3D:00000002, previousRequestId: no previous request id, message: Client has NOT been authenticated for /api/courses/create and pipeline error set. Request for
authenticated route /api/courses/create by was unauthenticated
warn: Ocelot.Responder.Middleware.ResponderMiddleware[0]
requestId: 0HMIUJ2BDCV3D:00000002, previousRequestId: no previous request id, message: Error Code: UnauthenticatedError Message: Request for authenticated route /api/courses/create
by was unauthenticated errors found in ResponderMiddleware. Setting error response for request path:/api/courses/create, request method: POST
Can anyone spot the mistake i’m making?
2
Answers
Try this, in startup
I had the same problem, to solve it you need to ensure that your JWT signature is valid, review the way how you are creating the JWT signature and then change the SignatureValidator.
Method to create token:
On Ocelot now you can configure the Authentication schema and signature validation.
ConfigureService:
And finally the Configuration method: