Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
1 task done
iikuzmychov opened this issue Dec 3, 2024 · 9 comments
Closed
1 task done
Labels
area-commandlinetools Includes: Command line tools, dotnet-dev-certs, dotnet-user-jwts, and OpenAPI feature-userjwts The `dotnet user-jwts` CLI tool

Comments

@iikuzmychov
Copy link

iikuzmychov commented Dec 3, 2024

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

@iikuzmychov iikuzmychov changed the title dotnet user-jwts produce incorrect configuration dotnet user-jwts create generates incorrect configuration Dec 3, 2024
@iikuzmychov iikuzmychov changed the title dotnet user-jwts create generates incorrect configuration dotnet user-jwts generates incorrect configuration Dec 3, 2024
@mkArtakMSFT mkArtakMSFT added area-commandlinetools Includes: Command line tools, dotnet-dev-certs, dotnet-user-jwts, and OpenAPI feature-userjwts The `dotnet user-jwts` CLI tool and removed area-security labels Dec 4, 2024
@iikuzmychov
Copy link
Author

For everyone who is seeking for temporary solution and don't want to read the whole article:

{
  "Authentication": {
    "Schemes": {
      "Bearer": {
        "ValidAudiences": [
          "http://localhost:5395",
          "https://localhost:7452"
        ],
-       "ValidIssuer": "dotnet-user-jwts"
+       "ValidIssuers": ["dotnet-user-jwts"]
      }
    }
  }
}

@iikuzmychov iikuzmychov changed the title dotnet user-jwts generates incorrect configuration dotnet user-jwts generates incorrect configuration which results in IDX10500 Dec 8, 2024
@dmytro-pryvedeniuk
Copy link

Because of this issue the default setup described in the documentation (https://learn.microsoft.com/en-us/aspnet/core/security/authentication/jwt-authn?view=aspnetcore-9.0&tabs=windows) simply does not work. API always returns 401. If you set log level for Microsoft.AspNetCore.Authentication to Information you can see "IDX10500: Signature validation failed. No security keys were provided to validate the signature." in the output. Changing ValidIssuer to ValidIssuers helps as a workaround.

Here (#52821 (comment)) satma0745 mentions the tests covering that ValidIssuer becomes a part of ValidIssuers collection, but it looks like GetIssuerSigningKeys is called BEFORE it happens.

@iikuzmychov
Copy link
Author

iikuzmychov commented Dec 8, 2024

Here (#52821 (comment)) satma0745 mentions the tests covering that ValidIssuer becomes a part of ValidIssuers collection, but it looks like GetIssuerSigningKeys is called BEFORE it happens.

Actually, the tests you are talking about were update since that comment. And from what I see they include both ValidIssuer & ValidIssuers config keys so it make them useless in order to verify the behavior described within this issue.

I would stay on that the problem comes from GetIssuerSigningKeys implementations. It ignores all security keys except the ones which contain specified issuers.

@dmytro-pryvedeniuk
Copy link

I would stay on that the problem comes from GetIssuerSigningKeys implementations. It ignores all security keys except the ones which contain specified issuers.

Don't you count ValidIssuer as "specified" one? For me it's the same as the issuers from ValidIssuers.
If you mean GetIssuerSigningKeys ignores ValidIssuer then I am with you.

@iikuzmychov
Copy link
Author

@dmytro-pryvedeniuk yes, I mean GetIssuerSigningKeys ignores ValidIssuer

@dmytro-pryvedeniuk
Copy link

Fixed in scope of #58996.

@ZuluNovember
Copy link

I'm still having this issue with macos. As described when I run dotnet user-jwts create my appsettings gets updated with:

  "Authentication": {
    "Schemes": {
      "Bearer": {
        "ValidAudiences": [
          "http://localhost:5179",
          "https://localhost:7108"
        ],
        "ValidIssuer": "dotnet-user-jwts"
      }
    }

I get error unless I update ValidIssuer to ValidIssuers like this:

  "Authentication": {
    "Schemes": {
      "Bearer": {
        "ValidAudiences": [
          "http://localhost:5179",
          "https://localhost:7108"
        ],
        "ValidIssuers": ["dotnet-user-jwts"]
      }
    }
  }
.NET SDK:
 Version:           9.0.101
 Commit:            eedb237549
 Workload version:  9.0.100-manifests.3068a692
 MSBuild version:   17.12.12+1cce77968

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  15.1
 OS Platform: Darwin
 RID:         osx-arm64
 Base Path:   /usr/local/share/dotnet/sdk/9.0.101/

.NET workloads installed:
There are no installed workloads to display.
Configured to use loose manifests when installing new manifests.

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

.NET SDKs installed:
  9.0.101 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 9.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 9.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

@dmytro-pryvedeniuk
Copy link

ZuluNovember, the fix is targeted for "9.0.x" version with "No due date" (see https://github.com/dotnet/aspnetcore/milestone/329?closed=1). It's not released as I understand.

@martincostello
Copy link
Member

#59473 shows the milestone as 9.0.2, so that would be February's Update Tuesday at the earliest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-commandlinetools Includes: Command line tools, dotnet-dev-certs, dotnet-user-jwts, and OpenAPI feature-userjwts The `dotnet user-jwts` CLI tool
Projects
None yet
5 participants