We are integrating Servicestack V8.6 with an existing OIDC provider. I have implemented the addServices according to the documentation provided here: JWT Identity Auth
Source programm.cs
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
using var client = new HttpClient();
var discoveryDocumentAddress = builder.Configuration["Identity:DiscoveryDocument"];
var audience = builder.Configuration["Identity:Audience"];
var discoveryDocument = client.GetDiscoveryDocumentAsync(discoveryDocumentAddress).Result;
var key = discoveryDocument.KeySet.Keys.First(k => k.Alg == OidcConstants.Algorithms.Asymmetric.RS256);
var publicKey = new RSAParameters
{
Modulus = WebEncoders.Base64UrlDecode(key.N),
Exponent = WebEncoders.Base64UrlDecode(key.E)
};
options.Audience = "AUDIENCE";
options.Authority = "https://AUTHORITY";
options.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = new RsaSecurityKey(publicKey),
ValidAudience = audience,
ValidIssuer = "ISSUER",
};
});
In Configure.Authentication.cs I have added the Authentication feature:
If I try to login with a valid JWT Token in API Explorer (API Endpoint api/Authenticate), I get an HTTP 401 Unauthorised although, ASPNetCore.Authentication Middleware reports the Token to be valid
08:53:33 DBG]:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler Successfully validated the token.
[08:53:33 DBG]:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler AuthenticationScheme: Bearer was successfully authenticated.
What am I missing?
Full Log stack:
[08:53:33 INF]:Microsoft.AspNetCore.Hosting.Diagnostics Request starting HTTP/1.1 POST http://localhost:5000/api/Authenticate - application/json 2
[08:53:33 DBG]:Microsoft.AspNetCore.Routing.Matching.DfaMatcher 1 candidate(s) found for the request path '/api/Authenticate'
[08:53:33 DBG]:Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware Request matched endpoint 'HTTP: POST /api/Authenticate'
[08:53:33 DBG]:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler Successfully validated the token.
[08:53:33 DBG]:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler AuthenticationScheme: Bearer was successfully authenticated.
[08:53:33 INF]:Microsoft.AspNetCore.Routing.EndpointMiddleware Executing endpoint 'HTTP: POST /api/Authenticate'
[08:53:33 DBG]:ServiceStack.Host.Handlers.HttpAsyncTaskHandler CreateContentTypeRequest/hasContentBody:True:POST:application/json:2:
[08:53:33 DBG]:Microsoft.AspNetCore.Server.Kestrel Connection id "0HNAN8MEQA9H2", Request id "0HNAN8MEQA9H2:00000003": started reading request body.
[08:53:33 DBG]:Microsoft.AspNetCore.Server.Kestrel Connection id "0HNAN8MEQA9H2", Request id "0HNAN8MEQA9H2:00000003": done reading request body.
[08:53:33 INF]:Microsoft.AspNetCore.Routing.EndpointMiddleware Executed endpoint 'HTTP: POST /api/Authenticate'
[08:53:33 DBG]:Microsoft.AspNetCore.Server.Kestrel.Connections Connection id "0HNAN8MEQA9H2" completed keep alive response.
[08:53:33 INF]:Microsoft.AspNetCore.Hosting.Diagnostics Request finished HTTP/1.1 POST http://localhost:5000/api/Authenticate - 401 0 null 112.9998ms
Note this is using ASP .NET Identity JWT Authentication, we don’t provide support for integration with external third party Authentication providers.
You should ensure you have a working JWT configuration with your ASP .NET App before using ServiceStack, e.g. can you verify you can access a protected Minimal API with your JWT Token?
I can confirm that a simple /hello request works perfectly
[09:38:23 DBG]:Microsoft.AspNetCore.Routing.Matching.DfaMatcher 1 candidate(s) found for the request path '/hello'
[09:38:23 DBG]:Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware Request matched endpoint 'HTTP: GET /hello'
[09:38:23 DBG]:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler Successfully validated the token.
[09:38:23 DBG]:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler AuthenticationScheme: Bearer was successfully authenticated.
[09:38:23 DBG]:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService Authorization was successful.
[09:38:23 INF]:Microsoft.AspNetCore.Routing.EndpointMiddleware Executing endpoint 'HTTP: GET /hello'
[09:38:23 INF]:Microsoft.AspNetCore.Routing.EndpointMiddleware Executed endpoint 'HTTP: GET /hello'
[09:38:23 DBG]:Microsoft.AspNetCore.Server.Kestrel.Connections Connection id "0HNANQCQEBLBS" completed keep alive response.
[09:38:23 INF]:Microsoft.AspNetCore.Hosting.Diagnostics Request finished HTTP/1.1 GET http://localhost:5000/hello - 200 null text/plain; charset=utf-8 9.0069ms
[09:38:23 DBG]:Microsoft.AspNetCore.Server.Kestrel Connection id "0HNANQCQEBLBS", Request id "0HNANQCQEBLBS:00000002": started reading request body.
[09:38:23 DBG]:Microsoft.AspNetCore.Server.Kestrel Connection id "0HNANQCQEBLBS", Request id "0HNANQCQEBLBS:00000002": done reading request body.
We have been using an IdentityServer4 as our external OIDC provider for years with servicestack in a non minimalistic API Setup and it worked perfectly.
With the Setup of a new project we wanted to update to the latest ASPNet Core standards
Can you try again after removing this line? The default SessionFactory uses a Session with an IRequireClaimsPrincipal which is needed for Identity Auth providers.