Skip to content

dotnet user-jwts generates incorrect configuration which results in IDX10500 #59277

@iikuzmychov

Description

@iikuzmychov

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

My pipeline looks like this (simplified):

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddAuthentication(defaultScheme: JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer();

builder.Services.AddAuthorization();

builder.Services.AddControllers(options =>
{
    options.Filters.Add(new AuthorizeFilter());
});

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

I'm running dotnet user-jwts create and it updates my configuration with the next data:

  • appsettings.Development.json:
{
  "Authentication": {
    "Schemes": {
      "Bearer": {
        "ValidAudiences": [
          "http://localhost:5395",
          "https://localhost:7452"
        ],
        "ValidIssuer": "dotnet-user-jwts"
      }
    }
  }
}
  • secrets.json (formatted):
{
   "Authentication:Schemes:Bearer:SigningKeys": [
      {
         "Id": "ec444f0c",
         "Issuer": "dotnet-user-jwts",
         "Value": "<KEY>",
         "Length": 32
      }
   ]
}

The problem is once I'm trying authenticate I got the next exception:

IDX10500: Signature validation failed. No security keys were provided to validate the signature.

The reason of this is the breaking change of JwtBearerConfigureOptions:

var issuer = configSection[nameof(TokenValidationParameters.ValidIssuer)];
var issuers = configSection.GetSection(nameof(TokenValidationParameters.ValidIssuers)).GetChildren().Select(iss => iss.Value).ToList();
-if (issuer is not null)
-{
-     issuers.Add(issuer);
-}
var audience = configSection[nameof(TokenValidationParameters.ValidAudience)];
var audiences = configSection.GetSection(nameof(TokenValidationParameters.ValidAudiences)).GetChildren().Select(aud => aud.Value).ToList();
-if (audience is not null)
-{
-    audiences.Add(audience);
-}

IssuerSigningKeys is filling in using this code:

options.TokenValidationParameters = new()
{
    // ...
    ValidateIssuerSigningKey = true,
    IssuerSigningKeys = GetIssuerSigningKeys(configSection, issuers),
};

where GetIssuerSigningKeys is iterating over specified issuers only:

private static IEnumerable<SecurityKey> GetIssuerSigningKeys(IConfiguration configuration, List<string?> issuers)
{
    foreach (var issuer in issuers)
    {
        var signingKey = configuration.GetSection("SigningKeys")
            .GetChildren()
            .SingleOrDefault(key => key["Issuer"] == issuer);
        if (signingKey is not null && signingKey["Value"] is string keyValue)
        {
            yield return new SymmetricSecurityKey(Convert.FromBase64String(keyValue));
        }
    }
}

As a result, Authentication:Schemes:Bearer:SigningKey config section will be ignored at all.

Expected Behavior

Either dotnet user-jwts tool should generate "ValidIssuers" instead of "ValidIssuer" or JwtBearerConfigureOptions logic should be changed.

I'm not really sure why GetIssuerSigningKeys was made in a way to respect only the keys for specified issuers instead of respect all the founded keys. Maybe it will have more sense to fix GetIssuerSigningKeys instead of fixing the dotnet user-jwts tool, but it will cause a one more breaking change 😥

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

9.0.100

Anything else?

.NET SDK:
Version: 9.0.100
Commit: 59db016f11
Workload version: 9.0.100-manifests.3068a692
MSBuild version: 17.12.7+5b8665660

Runtime Environment:
OS Name: Windows
OS Version: 10.0.19045
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\9.0.100\

.NET workloads installed:
[aspire]
Installation Source: VS 17.13.35507.96
Manifest Version: 8.2.2/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.2\WorkloadManifest.json
Install Type: Msi

Configured to use loose manifests when installing new manifests.

Host:
Version: 9.0.0
Architecture: x64
Commit: 9d5a6a9aa4

.NET SDKs installed:
6.0.404 [C:\Program Files\dotnet\sdk]
7.0.100 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]
9.0.100-rc.2.24474.11 [C:\Program Files\dotnet\sdk]
9.0.100 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.0-rc.2.24474.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.0-rc.2.24473.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.12 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.0-rc.2.24474.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
Not set

global.json file:
Not found

Learn more:
https://aka.ms/dotnet/info

Download .NET:
https://aka.ms/dotnet/download

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-commandlinetoolsIncludes: Command line tools, dotnet-dev-certs, dotnet-user-jwts, and OpenAPIfeature-userjwtsThe `dotnet user-jwts` CLI tool

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions