diff --git a/src/Security/Authentication/JwtBearer/src/JwtBearerConfigureOptions.cs b/src/Security/Authentication/JwtBearer/src/JwtBearerConfigureOptions.cs index 1ec03cca626c..796ddd9150b1 100644 --- a/src/Security/Authentication/JwtBearer/src/JwtBearerConfigureOptions.cs +++ b/src/Security/Authentication/JwtBearer/src/JwtBearerConfigureOptions.cs @@ -47,7 +47,10 @@ public void Configure(string? name, JwtBearerOptions options) var audience = configSection[nameof(TokenValidationParameters.ValidAudience)]; var audiences = configSection.GetSection(nameof(TokenValidationParameters.ValidAudiences)).GetChildren().Select(aud => aud.Value).ToList(); - options.Authority = configSection[nameof(options.Authority)] ?? options.Authority; + if (!string.IsNullOrWhiteSpace(configSection[nameof(options.Authority)])) + { + options.Authority = configSection[nameof(options.Authority)]; + } options.BackchannelTimeout = StringHelpers.ParseValueOrDefault(configSection[nameof(options.BackchannelTimeout)], _invariantTimeSpanParse, options.BackchannelTimeout); options.Challenge = configSection[nameof(options.Challenge)] ?? options.Challenge; options.ForwardAuthenticate = configSection[nameof(options.ForwardAuthenticate)] ?? options.ForwardAuthenticate; @@ -58,7 +61,10 @@ public void Configure(string? name, JwtBearerOptions options) options.ForwardSignOut = configSection[nameof(options.ForwardSignOut)] ?? options.ForwardSignOut; options.IncludeErrorDetails = StringHelpers.ParseValueOrDefault(configSection[nameof(options.IncludeErrorDetails)], bool.Parse, options.IncludeErrorDetails); options.MapInboundClaims = StringHelpers.ParseValueOrDefault( configSection[nameof(options.MapInboundClaims)], bool.Parse, options.MapInboundClaims); - options.MetadataAddress = configSection[nameof(options.MetadataAddress)] ?? options.MetadataAddress; + if (!string.IsNullOrWhiteSpace(configSection[nameof(options.MetadataAddress)])) + { + options.MetadataAddress = configSection[nameof(options.MetadataAddress)]!; + } options.RefreshInterval = StringHelpers.ParseValueOrDefault(configSection[nameof(options.RefreshInterval)], _invariantTimeSpanParse, options.RefreshInterval); options.RefreshOnIssuerKeyNotFound = StringHelpers.ParseValueOrDefault(configSection[nameof(options.RefreshOnIssuerKeyNotFound)], bool.Parse, options.RefreshOnIssuerKeyNotFound); options.RequireHttpsMetadata = StringHelpers.ParseValueOrDefault(configSection[nameof(options.RequireHttpsMetadata)], bool.Parse, options.RequireHttpsMetadata); diff --git a/src/Security/Authentication/test/JwtBearerTests_Handler.cs b/src/Security/Authentication/test/JwtBearerTests_Handler.cs index ff8311352ed9..ed387a5df4b6 100644 --- a/src/Security/Authentication/test/JwtBearerTests_Handler.cs +++ b/src/Security/Authentication/test/JwtBearerTests_Handler.cs @@ -1357,4 +1357,67 @@ private static (string tokenText, SymmetricSecurityKey key) CreateStandardTokenA var tokenText = new JwtSecurityTokenHandler().WriteToken(token); return (tokenText, key); } + + [Fact] + public void AuthorityNotSetFromEmptyConfiguration() + { + // Arrange + var services = new ServiceCollection(); + var config = new ConfigurationBuilder().AddInMemoryCollection([ + new("Authentication:Schemes:Bearer:Authority", ""), + new("Authentication:Schemes:Bearer:MetadataAddress", ""), + ]).Build(); + services.AddSingleton(config); + + // Act + RegisterAuth(services.AddAuthentication()); + var sp = services.BuildServiceProvider(); + + // Assert + var jwtBearerOptions = sp.GetRequiredService>().Get(JwtBearerDefaults.AuthenticationScheme); + Assert.Null(jwtBearerOptions.Authority); + Assert.Null(jwtBearerOptions.MetadataAddress); + } + + [Fact] + public void AuthorityNotSetFromWhitespaceConfiguration() + { + // Arrange + var services = new ServiceCollection(); + var config = new ConfigurationBuilder().AddInMemoryCollection([ + new("Authentication:Schemes:Bearer:Authority", " "), + new("Authentication:Schemes:Bearer:MetadataAddress", " "), + ]).Build(); + services.AddSingleton(config); + + // Act + RegisterAuth(services.AddAuthentication()); + var sp = services.BuildServiceProvider(); + + // Assert + var jwtBearerOptions = sp.GetRequiredService>().Get(JwtBearerDefaults.AuthenticationScheme); + Assert.Null(jwtBearerOptions.Authority); + Assert.Null(jwtBearerOptions.MetadataAddress); + } + + [Fact] + public void AuthoritySetFromValidConfiguration() + { + // Arrange + var services = new ServiceCollection(); + var config = new ConfigurationBuilder().AddInMemoryCollection([ + new("Authentication:Schemes:Bearer:Authority", "https://example.com"), + new("Authentication:Schemes:Bearer:MetadataAddress", "https://example.com/.well-known/openid-configuration"), + ]).Build(); + services.AddSingleton(config); + + // Act + RegisterAuth(services.AddAuthentication()); + var sp = services.BuildServiceProvider(); + + // Assert + var jwtBearerOptions = sp.GetRequiredService>().Get(JwtBearerDefaults.AuthenticationScheme); + Assert.Equal("https://example.com", jwtBearerOptions.Authority); + Assert.Equal("https://example.com/.well-known/openid-configuration", jwtBearerOptions.MetadataAddress); + } }