Skip to content

Commit 97d1829

Browse files
authored
Fix loading dotnet user-jwts config (#59425)
1 parent ef3a813 commit 97d1829

File tree

5 files changed

+59
-7
lines changed

5 files changed

+59
-7
lines changed

src/Security/Authentication/JwtBearer/src/JwtBearerConfigureOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public void Configure(string? name, JwtBearerOptions options)
7272
ValidAudiences = audiences,
7373
ValidAudience = audience,
7474
ValidateIssuerSigningKey = true,
75-
IssuerSigningKeys = GetIssuerSigningKeys(configSection, issuers),
75+
IssuerSigningKeys = GetIssuerSigningKeys(configSection, [issuer, ..issuers]),
7676
};
7777
}
7878

src/Security/Authentication/test/JwtBearerTests_Handler.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,7 @@ public async Task ExpirationAndIssuedWhenMinOrMaxValue()
957957
public void CanReadJwtBearerOptionsFromConfig()
958958
{
959959
var services = new ServiceCollection();
960+
var key = "qPG6tDtfxFYZifHW3sEueQ==";
960961
var config = new ConfigurationBuilder().AddInMemoryCollection([
961962
new("Authentication:Schemes:Bearer:ValidIssuer", "dotnet-user-jwts"),
962963
new("Authentication:Schemes:Bearer:ValidIssuers:0", "dotnet-user-jwts-2"),
@@ -965,6 +966,9 @@ public void CanReadJwtBearerOptionsFromConfig()
965966
new("Authentication:Schemes:Bearer:BackchannelTimeout", "00:01:00"),
966967
new("Authentication:Schemes:Bearer:RequireHttpsMetadata", "false"),
967968
new("Authentication:Schemes:Bearer:SaveToken", "True"),
969+
new("Authentication:Schemes:Bearer:SigningKeys:0:Issuer", "dotnet-user-jwts"),
970+
new("Authentication:Schemes:Bearer:SigningKeys:0:Value", key),
971+
new("Authentication:Schemes:Bearer:SigningKeys:0:Length", "32"),
968972
]).Build();
969973
services.AddSingleton<IConfiguration>(config);
970974

@@ -987,6 +991,10 @@ public void CanReadJwtBearerOptionsFromConfig()
987991
Assert.True(jwtBearerOptions.MapInboundClaims);
988992
Assert.True(jwtBearerOptions.TokenValidationParameters.ValidateIssuer);
989993
Assert.True(jwtBearerOptions.TokenValidationParameters.ValidateAudience);
994+
995+
var securityKey = Assert.Single(jwtBearerOptions.TokenValidationParameters.IssuerSigningKeys);
996+
var symmetricKey = Assert.IsType<SymmetricSecurityKey>(securityKey);
997+
Assert.Equal(key, Convert.ToBase64String(symmetricKey.Key));
990998
}
991999

9921000
[Fact]

src/Tools/Tools.slnf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"src\\Hosting\\Abstractions\\src\\Microsoft.AspNetCore.Hosting.Abstractions.csproj",
3030
"src\\Hosting\\Hosting\\src\\Microsoft.AspNetCore.Hosting.csproj",
3131
"src\\Hosting\\Server.Abstractions\\src\\Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj",
32+
"src\\Hosting\\TestHost\\src\\Microsoft.AspNetCore.TestHost.csproj",
3233
"src\\Html.Abstractions\\src\\Microsoft.AspNetCore.Html.Abstractions.csproj",
3334
"src\\Http\\Authentication.Abstractions\\src\\Microsoft.AspNetCore.Authentication.Abstractions.csproj",
3435
"src\\Http\\Authentication.Core\\src\\Microsoft.AspNetCore.Authentication.Core.csproj",
@@ -109,9 +110,9 @@
109110
"src\\Tools\\Extensions.ApiDescription.Server\\src\\Microsoft.Extensions.ApiDescription.Server.csproj",
110111
"src\\Tools\\FirstRunCertGenerator\\src\\Microsoft.AspNetCore.DeveloperCertificates.XPlat.csproj",
111112
"src\\Tools\\FirstRunCertGenerator\\test\\Microsoft.AspNetCore.DeveloperCertificates.XPlat.Tests.csproj",
113+
"src\\Tools\\GetDocumentInsider\\sample\\GetDocumentSample.csproj",
112114
"src\\Tools\\GetDocumentInsider\\src\\GetDocument.Insider.csproj",
113115
"src\\Tools\\GetDocumentInsider\\tests\\GetDocumentInsider.Tests.csproj",
114-
"src\\Tools\\GetDocumentInsider\\sample\\GetDocumentSample.csproj",
115116
"src\\Tools\\LinkabilityChecker\\LinkabilityChecker.csproj",
116117
"src\\Tools\\Microsoft.dotnet-openapi\\src\\Microsoft.dotnet-openapi.csproj",
117118
"src\\Tools\\Microsoft.dotnet-openapi\\test\\dotnet-microsoft.openapi.Tests.csproj",
@@ -125,4 +126,4 @@
125126
"src\\WebEncoders\\src\\Microsoft.Extensions.WebEncoders.csproj"
126127
]
127128
}
128-
}
129+
}

src/Tools/dotnet-user-jwts/test/UserJwtsTests.cs

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.IdentityModel.Tokens.Jwt;
5+
using System.Security.Claims;
6+
using System.Text.Json;
7+
using System.Text.Json.Nodes;
8+
using System.Text.RegularExpressions;
9+
using Microsoft.AspNetCore.Builder;
410
using Microsoft.AspNetCore.InternalTesting;
11+
using Microsoft.AspNetCore.TestHost;
12+
using Microsoft.Extensions.Configuration;
513
using Microsoft.Extensions.Configuration.UserSecrets;
14+
using Microsoft.Extensions.DependencyInjection;
615
using Microsoft.Extensions.Tools.Internal;
716
using Xunit.Abstractions;
8-
using System.Text.RegularExpressions;
9-
using System.Text.Json;
10-
using System.Text.Json.Nodes;
11-
using System.IdentityModel.Tokens.Jwt;
1217

1318
namespace Microsoft.AspNetCore.Authentication.JwtBearer.Tools.Tests;
1419

@@ -62,6 +67,38 @@ public void Create_WritesGeneratedTokenToDisk()
6267
Assert.Contains("dotnet-user-jwts", File.ReadAllText(appsettings));
6368
}
6469

70+
[Fact]
71+
public async Task Create_TokenAcceptedByJwtBearerHandler()
72+
{
73+
var project = Path.Combine(fixture.CreateProject(), "TestProject.csproj");
74+
var appsettings = Path.Combine(Path.GetDirectoryName(project), "appsettings.Development.json");
75+
var secrets = PathHelper.GetSecretsPathFromSecretsId(fixture.TestSecretsId);
76+
var app = new Program(_console);
77+
78+
app.Run(["create", "--project", project, "-o", "token"]);
79+
var token = _console.GetOutput().Trim();
80+
81+
var builder = WebApplication.CreateEmptyBuilder(new());
82+
builder.WebHost.UseTestServer();
83+
84+
builder.Configuration.AddJsonFile(appsettings);
85+
builder.Configuration.AddJsonFile(secrets);
86+
87+
builder.Services.AddRouting();
88+
builder.Services.AddAuthentication().AddJwtBearer();
89+
builder.Services.AddAuthorization();
90+
91+
using var webApp = builder.Build();
92+
webApp.MapGet("/secret", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}!")
93+
.RequireAuthorization();
94+
95+
await webApp.StartAsync();
96+
97+
var client = webApp.GetTestClient();
98+
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
99+
Assert.Equal($"Hello {Environment.UserName}!", await client.GetStringAsync("/secret"));
100+
}
101+
65102
[Fact]
66103
public void Create_CanModifyExistingScheme()
67104
{

src/Tools/dotnet-user-jwts/test/dotnet-user-jwts.Tests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,10 @@
1414
<ProjectReference Include="..\src\dotnet-user-jwts.csproj" />
1515
</ItemGroup>
1616

17+
<ItemGroup>
18+
<Reference Include="Microsoft.AspNetCore" />
19+
<Reference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
20+
<Reference Include="Microsoft.AspNetCore.TestHost" />
21+
</ItemGroup>
22+
1723
</Project>

0 commit comments

Comments
 (0)