-
Notifications
You must be signed in to change notification settings - Fork 255
Description
Microsoft.Identity.Web Library
Microsoft.Identity.Web
Microsoft.Identity.Web version
2.13.4-preview
Web app
Sign-in users and call web APIs
Web API
Protected web APIs call downstream web APIs
Token cache serialization
In-memory caches
Description
A change in .NET 8 does no longer allow the service collection to be modified in callbacks to options.
Reproduction steps
Update the CIAM samples (for instance) to .NET 8 and Id.Web 2.13.4-preview
Run
Error message
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: The service collection cannot be modified because it is read-only.
at Microsoft.Extensions.DependencyInjection.ServiceCollection.ThrowReadOnlyException()
at Microsoft.Extensions.DependencyInjection.ServiceCollection.System.Collections.Generic.ICollection<Microsoft.Extensions.DependencyInjection.ServiceDescriptor>.Add(ServiceDescriptor item)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(IServiceCollection services, Type serviceType, Func2 implementationFactory) at Microsoft.Extensions.Options.OptionsBuilder1.Configure[TDep](Action2 configureOptions) at Microsoft.Extensions.DependencyInjection.MetricsServiceExtensions.AddMetrics(IServiceCollection services) at Microsoft.Extensions.DependencyInjection.HttpClientFactoryServiceCollectionExtensions.AddHttpClient(IServiceCollection services) at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilderWithConfiguration.<EnableTokenAcquisitionToCallDownstreamApi>b__1_0(ConfidentialClientApplicationOptions options) at Microsoft.Extensions.Options.OptionsFactory1.Create(String name)
at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy1.CreateValue() at Microsoft.Extensions.Options.OptionsCache1.GetOrAdd[TArg](String name, Func3 createOptions, TArg factoryArgument) at Microsoft.Extensions.Options.OptionsMonitor1.Get(String name)
at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>c__DisplayClass11_0.b__0(OpenIdConnectOptions options, IMergedOptionsStore mergedOptionsMonitor, IOptionsMonitor1 ccaOptionsMonitor, IOptions1 ccaOptions)
at Microsoft.Extensions.Options.ConfigureNamedOptions4.Configure(String name, TOptions options) at Microsoft.Extensions.Options.OptionsFactory1.Create(String name)
at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy1.CreateValue() at Microsoft.Extensions.Options.OptionsCache1.GetOrAdd[TArg](String name, Func3 createOptions, TArg factoryArgument) at Microsoft.Extensions.Options.OptionsMonitor1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler1.InitializeAsync(AuthenticationScheme scheme, HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context) fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] An unhandled exception has occurred while executing the request. System.InvalidOperationException: The service collection cannot be modified because it is read-only. at Microsoft.Extensions.DependencyInjection.ServiceCollection.ThrowReadOnlyException() at Microsoft.Extensions.DependencyInjection.ServiceCollection.System.Collections.Generic.ICollection<Microsoft.Extensions.DependencyInjection.ServiceDescriptor>.Add(ServiceDescriptor item) at Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(IServiceCollection services, Type serviceType, Func2 implementationFactory)
at Microsoft.Extensions.Options.OptionsBuilder1.Configure[TDep](Action2 configureOptions)
at Microsoft.Extensions.DependencyInjection.MetricsServiceExtensions.AddMetrics(IServiceCollection services)
at Microsoft.Extensions.DependencyInjection.HttpClientFactoryServiceCollectionExtensions.AddHttpClient(IServiceCollection services)
at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilderWithConfiguration.b__1_0(ConfidentialClientApplicationOptions options)
at Microsoft.Extensions.Options.OptionsFactory1.Create(String name) at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache1.GetOrAdd[TArg](String name, Func3 createOptions, TArg factoryArgument)
at Microsoft.Extensions.Options.OptionsMonitor1.Get(String name) at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>c__DisplayClass11_0.<WebAppCallsWebApiImplementation>b__0(OpenIdConnectOptions options, IMergedOptionsStore mergedOptionsMonitor, IOptionsMonitor1 ccaOptionsMonitor, IOptions1 ccaOptions) at Microsoft.Extensions.Options.ConfigureNamedOptions4.Configure(String name, TOptions options)
at Microsoft.Extensions.Options.OptionsFactory1.Create(String name) at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location ---
at System.Lazy1.CreateValue() at Microsoft.Extensions.Options.OptionsCache1.GetOrAdd[TArg](String name, Func3 createOptions, TArg factoryArgument) at Microsoft.Extensions.Options.OptionsMonitor1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
Id Web logs
No response
Relevant code snippets
public new MicrosoftIdentityAppCallsWebApiAuthenticationBuilder EnableTokenAcquisitionToCallDownstreamApi(
IEnumerable<string>? initialScopes = null)
{
+ Services.AddHttpClient(); // should be outside
return EnableTokenAcquisitionToCallDownstreamApi(
options =>
{
ConfigurationSection?.Bind(options);
if (AppServicesAuthenticationInformation.IsAppServicesAadAuthenticationEnabled)
{
options.ClientId = AppServicesAuthenticationInformation.ClientId;
options.ClientSecret = AppServicesAuthenticationInformation.ClientSecret;
options.Instance = AppServicesAuthenticationInformation.Issuer;
}
- Services.AddHttpClient(); // shouldn't be in the callback
},
initialScopes);
}Regression
No response
Expected behavior
No exception