diff --git a/src/Security/src/Authentication.CloudFoundryBase/CloudFoundryHelper.cs b/src/Security/src/Authentication.CloudFoundryBase/CloudFoundryHelper.cs
index 7709557806..3bc4470dd0 100644
--- a/src/Security/src/Authentication.CloudFoundryBase/CloudFoundryHelper.cs
+++ b/src/Security/src/Authentication.CloudFoundryBase/CloudFoundryHelper.cs
@@ -62,19 +62,17 @@ public static TokenValidationParameters GetTokenValidationParameters(TokenValida
var tokenValidator = new CloudFoundryTokenValidator(options ?? new AuthServerOptions());
parameters.IssuerValidator = tokenValidator.ValidateIssuer;
- parameters.AudienceValidator = tokenValidator.ValidateAudience;
-
- CloudFoundryTokenKeyResolver tkr;
- if (options is null)
- {
- tkr = new CloudFoundryTokenKeyResolver(keyUrl, handler, validateCertificates);
- }
- else
+ if (!string.IsNullOrEmpty(parameters.ValidAudience) || parameters.ValidAudiences != null)
{
- tkr = new CloudFoundryTokenKeyResolver(keyUrl, handler, validateCertificates, options.ClientTimeout);
+ parameters.ValidateAudience = true;
+ parameters.AudienceValidator = tokenValidator.ValidateAudience;
}
- parameters.IssuerSigningKeyResolver = tkr.ResolveSigningKey;
+ var tokenKeyResolver = options is null
+ ? new CloudFoundryTokenKeyResolver(keyUrl, handler, validateCertificates)
+ : new CloudFoundryTokenKeyResolver(keyUrl, handler, validateCertificates, options.ClientTimeout);
+
+ parameters.IssuerSigningKeyResolver = tokenKeyResolver.ResolveSigningKey;
return parameters;
}
diff --git a/src/Security/src/Authentication.CloudFoundryBase/CloudFoundryTokenValidator.cs b/src/Security/src/Authentication.CloudFoundryBase/CloudFoundryTokenValidator.cs
index 4c42242d59..be1e0e6396 100644
--- a/src/Security/src/Authentication.CloudFoundryBase/CloudFoundryTokenValidator.cs
+++ b/src/Security/src/Authentication.CloudFoundryBase/CloudFoundryTokenValidator.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using Microsoft.IdentityModel.Tokens;
+using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
@@ -27,12 +28,7 @@ public CloudFoundryTokenValidator(AuthServerOptions options = null)
/// The issuer, if valid, else
public virtual string ValidateIssuer(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
{
- if (issuer.Contains("uaa"))
- {
- return issuer;
- }
-
- return null;
+ return issuer.Contains("uaa") ? issuer : null;
}
///
@@ -46,14 +42,19 @@ public virtual bool ValidateAudience(IEnumerable audiences, SecurityToke
{
foreach (var audience in audiences)
{
- if (audience.Equals(_options.ClientId))
+ if (audience.Equals(_options.ClientId, StringComparison.Ordinal))
+ {
+ return true;
+ }
+
+ if (validationParameters != null && (audience == validationParameters.ValidAudience || validationParameters.ValidAudiences?.Contains(audience) == true))
{
return true;
}
if (_options.AdditionalAudiences != null)
{
- var found = _options.AdditionalAudiences.Any(x => x.Equals(audience));
+ var found = _options.AdditionalAudiences.Any(x => x == audience);
if (found)
{
return true;
diff --git a/src/Security/src/Authentication.CloudFoundryCore/AuthenticationBuilderExtensions.cs b/src/Security/src/Authentication.CloudFoundryCore/AuthenticationBuilderExtensions.cs
index c6a6a49505..2a65501fcc 100644
--- a/src/Security/src/Authentication.CloudFoundryCore/AuthenticationBuilderExtensions.cs
+++ b/src/Security/src/Authentication.CloudFoundryCore/AuthenticationBuilderExtensions.cs
@@ -282,10 +282,7 @@ public static AuthenticationBuilder AddCloudFoundryIdentityCertificate(this Auth
/// configured to use application identity certificates
public static AuthenticationBuilder AddCloudFoundryIdentityCertificate(this AuthenticationBuilder builder, string authenticationScheme, Action configurer)
{
- builder.AddMutualTls(authenticationScheme, options =>
- {
- configurer?.Invoke(options);
- });
+ builder.AddMutualTls(authenticationScheme, configurer);
return builder;
}
diff --git a/src/Security/src/Authentication.CloudFoundryCore/CloudFoundryJwtBearerOptions.cs b/src/Security/src/Authentication.CloudFoundryCore/CloudFoundryJwtBearerOptions.cs
index c1ef7ef5e7..ecd0672008 100644
--- a/src/Security/src/Authentication.CloudFoundryCore/CloudFoundryJwtBearerOptions.cs
+++ b/src/Security/src/Authentication.CloudFoundryCore/CloudFoundryJwtBearerOptions.cs
@@ -24,7 +24,7 @@ public CloudFoundryJwtBearerOptions()
public bool Validate_Certificates { get; set; } = true;
///
- /// Gets or sets a value indicating whether gets a value indicating whether to validate auth server certificate
+ /// Gets or sets a value indicating whether to validate auth server certificate
///
public bool ValidateCertificates
{
@@ -39,7 +39,11 @@ public bool ValidateCertificates
public void SetEndpoints(string authDomain)
{
- JwtKeyUrl = (!string.IsNullOrWhiteSpace(authDomain)) ?
- authDomain + CloudFoundryDefaults.JwtTokenUri : JwtKeyUrl;
+ if (string.IsNullOrEmpty(JwtKeyUrl) || JwtKeyUrl == $"http://{CloudFoundryDefaults.OAuthServiceUrl}{CloudFoundryDefaults.JwtTokenUri}")
+ {
+ JwtKeyUrl = !string.IsNullOrWhiteSpace(authDomain)
+ ? authDomain + CloudFoundryDefaults.JwtTokenUri
+ : JwtKeyUrl;
+ }
}
}
\ No newline at end of file
diff --git a/src/Security/src/Authentication.CloudFoundryCore/CloudFoundryOpenIdConnectConfigurer.cs b/src/Security/src/Authentication.CloudFoundryCore/CloudFoundryOpenIdConnectConfigurer.cs
index 4af5df0629..62ab14128d 100644
--- a/src/Security/src/Authentication.CloudFoundryCore/CloudFoundryOpenIdConnectConfigurer.cs
+++ b/src/Security/src/Authentication.CloudFoundryCore/CloudFoundryOpenIdConnectConfigurer.cs
@@ -43,6 +43,8 @@ internal static void Configure(SsoServiceInfo si, OpenIdConnectOptions oidcOptio
oidcOptions.BackchannelHttpHandler = CloudFoundryHelper.GetBackChannelHandler(cfOptions.ValidateCertificates);
oidcOptions.CallbackPath = cfOptions.CallbackPath;
oidcOptions.ClaimsIssuer = cfOptions.ClaimsIssuer;
+ oidcOptions.MetadataAddress = cfOptions.MetadataAddress;
+ oidcOptions.RequireHttpsMetadata = cfOptions.RequireHttpsMetadata;
oidcOptions.ResponseType = cfOptions.ResponseType;
oidcOptions.SaveTokens = cfOptions.SaveTokens;
oidcOptions.SignInScheme = cfOptions.SignInScheme;
diff --git a/src/Security/src/Authentication.CloudFoundryCore/ServiceCollectionExtensions.cs b/src/Security/src/Authentication.CloudFoundryCore/ServiceCollectionExtensions.cs
index 04b03fc4a9..7ac40365dc 100644
--- a/src/Security/src/Authentication.CloudFoundryCore/ServiceCollectionExtensions.cs
+++ b/src/Security/src/Authentication.CloudFoundryCore/ServiceCollectionExtensions.cs
@@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Authentication.Certificate;
using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
@@ -23,13 +24,21 @@ public static class ServiceCollectionExtensions
/// Application Configuration
[Obsolete("The IConfiguration parameter is not used")]
public static void AddCloudFoundryContainerIdentity(this IServiceCollection services, IConfiguration configuration)
- => AddCloudFoundryContainerIdentity(services);
+ => AddCloudFoundryContainerIdentity(services, configurer: null);
///
/// Adds options and services to use Cloud Foundry container identity certificates
///
/// Service collection
public static void AddCloudFoundryContainerIdentity(this IServiceCollection services)
+ => AddCloudFoundryContainerIdentity(services, configurer: null);
+
+ ///
+ /// Adds options and services to use Cloud Foundry container identity certificates
+ ///
+ /// Service collection
+ /// Used to configure the
+ public static void AddCloudFoundryContainerIdentity(this IServiceCollection services, Action configurer)
{
if (services == null)
{
@@ -43,7 +52,11 @@ public static void AddCloudFoundryContainerIdentity(this IServiceCollection serv
services.AddSingleton();
services.AddHostedService();
services.AddSingleton();
- services.AddCertificateForwarding(opt => opt.CertificateHeader = "X-Forwarded-Client-Cert");
+ services.AddCertificateForwarding(opt =>
+ {
+ opt.CertificateHeader = "X-Forwarded-Client-Cert";
+ configurer?.Invoke(opt);
+ });
}
///
@@ -68,7 +81,15 @@ public static void AddCloudFoundryCertificateAuth(this IServiceCollection servic
/// Service collection
/// Used to configure the
public static void AddCloudFoundryCertificateAuth(this IServiceCollection services, Action configurer)
- => AddCloudFoundryCertificateAuth(services, CertificateAuthenticationDefaults.AuthenticationScheme, configurer);
+ => AddCloudFoundryCertificateAuth(services, CertificateAuthenticationDefaults.AuthenticationScheme, configurer, null);
+
+ ///
+ /// Adds options and services for Cloud Foundry container identity certificates along with certificate-based authentication and authorization
+ ///
+ /// Service collection
+ /// Used to configure the
+ public static void AddCloudFoundryCertificateAuth(this IServiceCollection services, Action configurer)
+ => AddCloudFoundryCertificateAuth(services, CertificateAuthenticationDefaults.AuthenticationScheme, null, configurer);
///
/// Adds options and services for Cloud Foundry container identity certificates along with certificate-based authentication and authorization
@@ -76,7 +97,7 @@ public static void AddCloudFoundryCertificateAuth(this IServiceCollection servic
/// Service collection
/// An identifier for this authentication mechanism. Default value is
public static void AddCloudFoundryCertificateAuth(this IServiceCollection services, string authenticationScheme)
- => AddCloudFoundryCertificateAuth(services, authenticationScheme, null);
+ => AddCloudFoundryCertificateAuth(services, authenticationScheme, null, null);
///
/// Adds options and services for Cloud Foundry container identity certificates along with certificate-based authentication and authorization
@@ -85,17 +106,27 @@ public static void AddCloudFoundryCertificateAuth(this IServiceCollection servic
/// An identifier for this authentication mechanism. Default value is
/// Used to configure the
public static void AddCloudFoundryCertificateAuth(this IServiceCollection services, string authenticationScheme, Action configurer)
+ => AddCloudFoundryCertificateAuth(services, authenticationScheme, configurer, null);
+
+ ///
+ /// Adds options and services for Cloud Foundry container identity certificates along with certificate-based authentication and authorization
+ ///
+ /// Service collection
+ /// An identifier for this authentication mechanism. Default value is
+ /// Used to configure the
+ /// Used to configure the
+ public static void AddCloudFoundryCertificateAuth(this IServiceCollection services, string authenticationScheme, Action configureMutualTlsAuthentication, Action configureCertificateForwarding)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}
- services.AddCloudFoundryContainerIdentity();
+ services.AddCloudFoundryContainerIdentity(configureCertificateForwarding);
services
.AddAuthentication(authenticationScheme)
- .AddCloudFoundryIdentityCertificate(authenticationScheme, configurer);
+ .AddCloudFoundryIdentityCertificate(authenticationScheme, configureMutualTlsAuthentication);
services.AddAuthorization(cfg =>
{
diff --git a/src/Security/test/Authentication.CloudFoundryBase.Test/CloudFoundryHelperTest.cs b/src/Security/test/Authentication.CloudFoundryBase.Test/CloudFoundryHelperTest.cs
index b6a018a9ab..3d0a5ef48e 100644
--- a/src/Security/test/Authentication.CloudFoundryBase.Test/CloudFoundryHelperTest.cs
+++ b/src/Security/test/Authentication.CloudFoundryBase.Test/CloudFoundryHelperTest.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
+using Microsoft.IdentityModel.Tokens;
using System;
using System.Text.Json;
using Xunit;
@@ -25,12 +26,27 @@ public void GetTokenValidationParameters_ReturnsExpected()
{
var parameters = CloudFoundryHelper.GetTokenValidationParameters(null, "https://foo.bar.com/keyurl", null, false);
Assert.False(parameters.ValidateAudience, "Audience validation should not be enabled by default");
+ Assert.Null(parameters.AudienceValidator);
Assert.True(parameters.ValidateIssuer, "Issuer validation should be enabled by default");
Assert.NotNull(parameters.IssuerValidator);
Assert.True(parameters.ValidateLifetime, "Token lifetime validation should be enabled by default");
Assert.NotNull(parameters.IssuerSigningKeyResolver);
}
+ [Fact]
+ public void GetTokenValidationParameters_ValidatesAudienceWhenProvided()
+ {
+ var tokenValidationParameters =
+ new TokenValidationParameters { ValidAudience = "some-api", ValidAudiences = new[] { "another-audience" } };
+ var parameters = CloudFoundryHelper.GetTokenValidationParameters(tokenValidationParameters, "https://foo.bar.com/keyurl", null, false);
+
+ Assert.True(parameters.ValidateAudience, "Audience validation should be enabled when ValidAudience or ValidAudiences are provided");
+ Assert.NotNull(parameters.AudienceValidator);
+ Assert.True(parameters.AudienceValidator(new[] { "some-api" }, null, tokenValidationParameters), "Validates single audience");
+ Assert.True(parameters.AudienceValidator(new[] { "another-audience" }, null, tokenValidationParameters), "Validates from list of audiences");
+ Assert.False(parameters.AudienceValidator(new[] { "invalid-audience" }, null, tokenValidationParameters), "Unlisted audience is not valid");
+ }
+
[Fact]
public void GetExpTime_FindsTime()
{
diff --git a/src/Security/test/Authentication.CloudFoundryBase.Test/CloudFoundryTokenValidatorTest.cs b/src/Security/test/Authentication.CloudFoundryBase.Test/CloudFoundryTokenValidatorTest.cs
index ec70ea02dc..ddfcce56d2 100644
--- a/src/Security/test/Authentication.CloudFoundryBase.Test/CloudFoundryTokenValidatorTest.cs
+++ b/src/Security/test/Authentication.CloudFoundryBase.Test/CloudFoundryTokenValidatorTest.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
+using Microsoft.IdentityModel.Tokens;
using Xunit;
namespace Steeltoe.Security.Authentication.CloudFoundry.Test;
@@ -19,4 +20,44 @@ public void ValidateIssuer_ValidatesCorrectly()
Assert.NotNull(uaaResult);
Assert.Null(foobarResult);
}
+
+ [Fact]
+ public void ValidateAudience_ValidatesFromAuthServerOptionsCorrectly()
+ {
+ var cftv = new CloudFoundryTokenValidator(new AuthServerOptions
+ {
+ ClientId = "test-client",
+ AdditionalAudiences = new[] { "additional-audience" }
+ });
+ var audiences = new[] { "profile", "some-api", "additional-audience" };
+ var result = cftv.ValidateAudience(audiences, null, null);
+ Assert.True(result);
+
+ audiences = new[] { "invalid-audience" };
+ result = cftv.ValidateAudience(audiences, null, null);
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void ValidateAudience_ValidatesFromTokenValidationParameters()
+ {
+ var cftv = new CloudFoundryTokenValidator();
+ var audiences = new[] { "profile", "some-api", "additional-audience" };
+ var validationParametersSingleAudience = new TokenValidationParameters { ValidAudience = "some-api" };
+ var result = cftv.ValidateAudience(audiences, null, validationParametersSingleAudience);
+ Assert.True(result, "Valid from single audience in TokenValidationParameters");
+
+ var validationParametersListOfAudiences = new TokenValidationParameters
+ {
+ ValidAudiences = new[] { "some-api" }
+ };
+ result = cftv.ValidateAudience(audiences, null, validationParametersListOfAudiences);
+ Assert.True(result, "Valid from audience list in TokenValidationParameters");
+
+ audiences = new[] { "invalid-audience" };
+ result = cftv.ValidateAudience(audiences, null, validationParametersSingleAudience);
+ Assert.False(result, "Invalid from single audience in TokenValidationParameters");
+ result = cftv.ValidateAudience(audiences, null, validationParametersSingleAudience);
+ Assert.False(result, "Invalid from audience list in TokenValidationParameters");
+ }
}
\ No newline at end of file
diff --git a/src/Security/test/Authentication.CloudFoundryCore.Test/CloudFoundryJwtBearerOptionsTest.cs b/src/Security/test/Authentication.CloudFoundryCore.Test/CloudFoundryJwtBearerOptionsTest.cs
index c50305ca31..5565c03430 100644
--- a/src/Security/test/Authentication.CloudFoundryCore.Test/CloudFoundryJwtBearerOptionsTest.cs
+++ b/src/Security/test/Authentication.CloudFoundryCore.Test/CloudFoundryJwtBearerOptionsTest.cs
@@ -18,14 +18,14 @@ public static TheoryData SetEndpointsData()
data.Add(string.Empty, DEFAULT_JWT_TOKEN_URL);
data.Add(" ", DEFAULT_JWT_TOKEN_URL);
- data.Add(default, DEFAULT_JWT_TOKEN_URL);
+ data.Add(null, DEFAULT_JWT_TOKEN_URL);
data.Add(newDomain, newDomain + CloudFoundryDefaults.JwtTokenUri);
return data;
}
[Fact]
- public void DefaultConstructor_SetsupDefaultOptions()
+ public void DefaultConstructor_SetsUpDefaultOptions()
{
var opts = new CloudFoundryJwtBearerOptions();
diff --git a/src/Security/test/Authentication.CloudFoundryCore.Test/CloudFoundryOpenIdConnectConfigurerTest.cs b/src/Security/test/Authentication.CloudFoundryCore.Test/CloudFoundryOpenIdConnectConfigurerTest.cs
index 997ed0e2e6..2544b674af 100644
--- a/src/Security/test/Authentication.CloudFoundryCore.Test/CloudFoundryOpenIdConnectConfigurerTest.cs
+++ b/src/Security/test/Authentication.CloudFoundryCore.Test/CloudFoundryOpenIdConnectConfigurerTest.cs
@@ -17,9 +17,18 @@ public class CloudFoundryOpenIdConnectConfigurerTest
public void Configure_NoServiceInfo_ReturnsExpected()
{
var oidcOptions = new OpenIdConnectOptions();
+ var cloudFoundryOptions = new CloudFoundryOpenIdConnectOptions
+ {
+ Authority = "http://localhost:8080/uaa",
+ MetadataAddress = "http://localhost:8080/.well-known/openid-configuration",
+ RequireHttpsMetadata = false,
+ ValidateCertificates = false
+ };
- CloudFoundryOpenIdConnectConfigurer.Configure(null, oidcOptions, new CloudFoundryOpenIdConnectOptions() { ValidateCertificates = false });
+ CloudFoundryOpenIdConnectConfigurer.Configure(null, oidcOptions, cloudFoundryOptions);
+ Assert.Equal("http://localhost:8080/uaa", oidcOptions.Authority);
+ Assert.Equal("http://localhost:8080/.well-known/openid-configuration", oidcOptions.MetadataAddress);
Assert.Equal(CloudFoundryDefaults.AuthenticationScheme, oidcOptions.ClaimsIssuer);
Assert.Equal(CloudFoundryDefaults.ClientId, oidcOptions.ClientId);
Assert.Equal(CloudFoundryDefaults.ClientSecret, oidcOptions.ClientSecret);
@@ -28,6 +37,7 @@ public void Configure_NoServiceInfo_ReturnsExpected()
Assert.Equal(CookieAuthenticationDefaults.AuthenticationScheme, oidcOptions.SignInScheme);
Assert.False(oidcOptions.SaveTokens);
Assert.NotNull(oidcOptions.BackchannelHttpHandler);
+ Assert.False(oidcOptions.RequireHttpsMetadata);
}
[Fact]
@@ -49,5 +59,6 @@ public void Configure_WithServiceInfo_ReturnsExpected()
Assert.Equal(CookieAuthenticationDefaults.AuthenticationScheme, oidcOptions.SignInScheme);
Assert.False(oidcOptions.SaveTokens);
Assert.Null(oidcOptions.BackchannelHttpHandler);
+ Assert.True(oidcOptions.RequireHttpsMetadata);
}
}
\ No newline at end of file
diff --git a/src/Security/test/Authentication.CloudFoundryCore.Test/ServiceCollectionExtensionsTest.cs b/src/Security/test/Authentication.CloudFoundryCore.Test/ServiceCollectionExtensionsTest.cs
index 5c4c3eb978..63e404773c 100644
--- a/src/Security/test/Authentication.CloudFoundryCore.Test/ServiceCollectionExtensionsTest.cs
+++ b/src/Security/test/Authentication.CloudFoundryCore.Test/ServiceCollectionExtensionsTest.cs
@@ -2,7 +2,9 @@
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
+using Microsoft.AspNetCore.Authentication.Certificate;
using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
@@ -10,6 +12,7 @@
using Steeltoe.Common.Security;
using Steeltoe.Security.Authentication.Mtls;
using System;
+using System.Security.Cryptography.X509Certificates;
using Xunit;
namespace Steeltoe.Security.Authentication.CloudFoundry.Test;
@@ -39,11 +42,54 @@ public void AddCloudFoundryCertificateAuth_AddsServices()
Assert.NotNull(provider.GetRequiredService>());
Assert.NotNull(provider.GetRequiredService());
Assert.NotNull(provider.GetRequiredService());
- var mtlsOpts = provider.GetRequiredService>();
- Assert.NotNull(mtlsOpts);
+ Assert.NotNull(provider.GetRequiredService>());
+ }
+
+ [Fact]
+ public void AddCloudFoundryCertificateAuth_SetsExpectedOptions()
+ {
+ var services = new ServiceCollection();
+ var config = new ConfigurationBuilder().Build();
+ services.AddSingleton(config);
+ services.AddLogging();
+
+ services.AddCloudFoundryCertificateAuth();
+ var provider = services.BuildServiceProvider();
+
+ var mutualTlsOptions = provider.GetRequiredService>();
+ var namedTlsOptions = mutualTlsOptions.Get(CertificateAuthenticationDefaults.AuthenticationScheme);
// confirm Events was set (in MutualTlsAuthenticationOptionsPostConfigurer.cs) vs being null by default
- Assert.NotNull(mtlsOpts.Value.Events);
- Assert.Null(new MutualTlsAuthenticationOptions().Events);
+ var defaultMTlsOptions = new MutualTlsAuthenticationOptions();
+ Assert.NotNull(namedTlsOptions.Events);
+ Assert.Null(defaultMTlsOptions.Events);
+ Assert.Equal(defaultMTlsOptions.RevocationMode, namedTlsOptions.RevocationMode);
+
+ var certificateForwardingOptions = provider.GetRequiredService>();
+ Assert.Equal("X-Forwarded-Client-Cert", certificateForwardingOptions.Value.CertificateHeader);
+ }
+
+ [Fact]
+ public void AddCloudFoundryCertificateAuth_AllowsOptionsCustomization()
+ {
+ var defaultMTlsOptions = new MutualTlsAuthenticationOptions();
+ var services = new ServiceCollection();
+ var config = new ConfigurationBuilder().AddInMemoryCollection().Build();
+ services.AddSingleton(config);
+ services.AddLogging();
+
+ static void TlsOptionsConfigurer(MutualTlsAuthenticationOptions options) => options.RevocationMode = X509RevocationMode.NoCheck;
+ static void CertificateForwardingConfigurer(CertificateForwardingOptions options) => options.CertificateHeader = "some-custom-header";
+
+ services.AddCloudFoundryCertificateAuth(CertificateAuthenticationDefaults.AuthenticationScheme, TlsOptionsConfigurer, CertificateForwardingConfigurer);
+ var provider = services.BuildServiceProvider();
+
+ var mutualTlsOptions = provider.GetRequiredService>();
+ var namedTlsOptions = mutualTlsOptions.Get(CertificateAuthenticationDefaults.AuthenticationScheme);
+ Assert.Equal(X509RevocationMode.NoCheck, namedTlsOptions.RevocationMode);
+ Assert.NotEqual(defaultMTlsOptions.RevocationMode, namedTlsOptions.RevocationMode);
+
+ var certForwardOptions = provider.GetRequiredService>();
+ Assert.Equal("some-custom-header", certForwardOptions.Value.CertificateHeader);
}
}
\ No newline at end of file