Keycloak Jwt Validation with C#

Hello together,

we want to validate a jwt we receive from keycloak in C# using openid connect.

We have this code:

builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.Authority = "http://localhost:8080";
        options.Audience = "my_client";
        options.RequireHttpsMetadata = false;
        options.MetadataAddress = "http://localhost:8080/realms/my_realm/.well-known/openid-configuration";

        options.Events = new JwtBearerEvents
        {
            OnAuthenticationFailed = context =>
            {
                context.Response.StatusCode = 401;
                context.Response.ContentType = "application/json";

                // Customize the error response
                var message = "Authentication failed: " + context.Exception.Message;
                var errorResponse = JsonSerializer.Serialize(new { message });
                return context.Response.WriteAsync(errorResponse);
            }
        };
    });

And we receive this error message:

Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HMUJNLSECPBD", Request id "0HMUJNLSECPBD:00000001": An unhandled exception was thrown by the application.
      System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'http://localhost:8080/realms/my_realm/.well-known/openid-configuration'.
       ---> System.TypeLoadException: Could not load type 'Microsoft.IdentityModel.Json.JsonConvert' from assembly 'Microsoft.IdentityModel.Tokens, Version=7.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
         at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
         at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
         at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
         at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.Microsoft.IdentityModel.Protocols.IConfigurationRetriever<Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration>.GetConfigurationAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
         at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
         --- End of inner exception stack trace ---
         at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
         at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
         at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
         at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
         at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
         at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Watch.BrowserRefresh.BrowserRefreshMiddleware.InvokeAsync(HttpContext context)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

Is there any configuration in keycloak we are missing or must we add something to our c# code?

Thank you for your help
Merlin

Have you checked that http://localhost:8080/realms/my_realm/.well-known/openid-configuration responds with a valid JSON-formatted configuration?

And I would try to configure the .NET’s JwtBearerOptions.Authority with the correct issuer:

options.Authority = "http://localhost:8080/realms/my_realm";

Thank you for your help, we fixed the issue. Some packages had a version missmatch.

Hi!,
I have same problem. Which of packages had been causing the problem?

Hi,
the
AspNetCore.Authentication.JWTBearer,
AspNetCore.Authentication.OpenIdConnect,
IdentityModel.JsonWebToken,
IdentityModel.Protocols,
IdentityModel.Protocols.OpenIdConnet and
IdentityModel.Tokens.
We set them all to 7.0.0