JwtAuthProviderReader - Not Authenticated

I had to split my API in 2. I now have a .Net8 api using IdentityJwtAuthProvider that signs my token using my cert rsa private key. This is fine, tokens are generated.

"JwtBearer": {
    "ValidIssuer": "https://myhost:4701",
    "ValidAudience": "https://myhost:4701"
  },

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.SaveToken = true;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["JwtBearer:ValidIssuer"],
            ValidAudience = builder.Configuration["JwtBearer:ValidAudience"],
            IssuerSigningKey = new RsaSecurityKey(SecurityContext.GetCertificate()?.GetRSAPrivateKey())
        };
    });

var auth = new AuthFeature(IdentityAuth.For<ApplicationUser>(options =>
                {
                    options.SessionFactory = () => new PEUserSession();
                    //options.CredentialsAuth();
                    options.JwtAuth(x =>
                    {
                        x.IncludeConvertSessionToTokenService = true;
                        x.RequireSecureConnection = true;
                        x.HashAlgorithm = SecurityAlgorithms.RsaSha256;
                        x.RestoreSessionFromState = false;
                        x.PersistSession = false;
                   ....

The second API is using .Net Framework 4.7.2 hosted as windows service which uses the JwtAuthProviderReader as follow:
The public key from my certificate from my .Net8 api is stored in the config as:

<RSAKeyValue><Modulus>p3+5Su...==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
var jwtReader = new JwtAuthProviderReader(AppSettings)
            {
                HashAlgorithm = "RS256",
                PublicKeyXml = AppSettings.GetString("PublicKeyXml"),
                RequireSecureConnection = true,
                UseTokenCookie = true,
                IncludeJwtInConvertSessionToTokenResponse = true,

Communication between the 2 is fine but as soon as I have a DTO with

[ValidateIsAuthenticated]

or a service with

[Authenticate]

Authentication fails with this error.

ServiceStack.HttpError: Not Authenticated
   at ServiceStack.TypeValidator.<ThrowIfNotValidAsync>d__34.MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/TypeValidators.cs:line 346
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at ServiceStack.Validators.<AssertTypeValidatorsAsync>d__20.MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Validators.cs:line 72
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at ServiceStack.Validation.ValidationFilters.<RequestFilterAsync>d__2.MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Validation/ValidationFilters.cs:line 27
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at ServiceStack.Validation.ValidationFilters.<RequestFilterAsync>d__0.MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Validation/ValidationFilters.cs:line 15
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at ServiceStack.ServiceStackHost.<ApplyRequestFiltersSingleAsync>d__457.MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/ServiceStackHost.Runtime.cs:line 217
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at ServiceStack.ServiceStackHost.<ApplyRequestFiltersAsync>d__456.MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/ServiceStackHost.Runtime.cs:line 145
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at ServiceStack.Host.RestHandler.<ProcessRequestAsync>d__14.MoveNext() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Host/RestHandler.cs:line 93

Not sure what I do wrong. Are my TokenValidationParameters ok? Do the JwtAuthProviderReader need to have other settings, like matching the ValidAudience?

ServiceStack Auth JWT Provider and IdentityJwtAuthProvider are not compatible.

I’d recommend using API Keys to communicate between ServiceStack Auth and Identity Auth Apps.

Thanks @mythz ,

But isn’t just a question of decoding a standard jwt token using a standard rsa public key?
Could you elaborate on what is the incompatibility?

The thing is that I need the Service A user’s context which I would get on Service B from the token.
Service B has no need for a UserAuth repo and only Service A can talk to it.

They’re completely separate implementations created independently that maintain different/incompatible JWT payloads.

You wont be able to use the same JWT between different Auth Providers but you should be able to read it within a Service, you’d need to use Identity Auth implementations to read an Identity Auth JWT and ServiceStack JWT implementation to read a ServiceStack Auth JWT.

Thank you very much for the explanation.