Impossible de valider le JWT signé RS256

Nov 19 2020

J'essaie d'implémenter le JWT signé (RS256) sur un webapi dotnet avec KeyCloak. Au démarrage de l'application, je peux voir les appels openid effectués à keycloak avec le contenu de réponse attendu (demandes indiquées ci-dessous).

Obtenez le jwks_url ici

GET https://localhost:8080/auth/realms/core/.well-known/openid-configuration

Obtenez les clés d'ici

GET https://localhost:8080/auth/realms/core/protocol/openid-connect/certs

Je reçois alors un access_token avec la demande ci-dessous

POST https://localhost:8080/auth/realms/core/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=password&client_id=admin-cli&username=jim&password=foobar

Je teste ensuite le point de terminaison suivant

[ApiController]
[Route("/")]
public class AppController : ControllerBase
{
    [Authorize]
    [HttpGet]
    public OkObjectResult Get()
    {
        return Ok("This is the secured page");
    }
}

avec cette demande

GET https://localhost:5001
Authorization: Bearer MY_TOKEN 

Mais j'ai toujours un 401

HTTP/1.1 401 Unauthorized
Content-Length: 0
Date: Wed, 18 Nov 2020 17:41:28 GMT
Server: Kestrel
Www-Authenticate: Bearer error="invalid_token", error_description="The signature key was not found"

La clé de signature (troisième «morceau») existe dans le jeton. Vous trouverez ci-dessous le code de validation JWT. Est-ce que je manque quelque chose?

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    var audience = Configuration["Jwt:Audience"];
    var issuer = Configuration["Jwt:Issuer"];
    bool.TryParse(Configuration["Jwt:RequireHttpsMetadata"], out var requireHttpsMetadata);

    IConfigurationManager<OpenIdConnectConfiguration> configurationManager =
        new ConfigurationManager<OpenIdConnectConfiguration>(
            $"{Configuration["Jwt:Authority"]}/auth/realms/core/.well-known/openid-configuration",
            new OpenIdConnectConfigurationRetriever());
    var openIdConfig =
        configurationManager.GetConfigurationAsync(CancellationToken.None).Result;

    services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.SaveToken = true;
            options.RequireHttpsMetadata = requireHttpsMetadata;
            options.TokenValidationParameters.IssuerSigningKeys = openIdConfig.SigningKeys;
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,

                ValidIssuer = issuer,
                ValidAudience = audience,
                ValidateIssuerSigningKey = true,
            };
        });
}

Réponses

1 monty Nov 19 2020 at 02:32

Puisque le JWT contient une signature (aka troisième morceau), j'interpréterais le message

"The signature key was not found"

qu'il y a un problème avec la validation de la signature.

Revérifiez les réponses / l'accessibilité de

GET https://localhost:8080/auth/realms/core/protocol/openid-connect/certs