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

System.InvalidOperationException: The service collection cannot be modified because it is read-only. on .NET 8 rc1 #2448

Closed
jmprieur opened this issue Sep 7, 2023 · 1 comment · Fixed by #2449
Labels
bug Something isn't working P1 question Further information is requested

Comments

@jmprieur
Copy link
Collaborator

jmprieur commented Sep 7, 2023

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

@jmprieur jmprieur added bug Something isn't working question Further information is requested P1 labels Sep 7, 2023
jmprieur added a commit that referenced this issue Sep 7, 2023
@jmprieur jmprieur mentioned this issue Sep 7, 2023
jmprieur added a commit that referenced this issue Sep 7, 2023
@jennyf19
Copy link
Collaborator

jennyf19 commented Sep 8, 2023

https://github.com/AzureAD/microsoft-identity-web/releases/tag/2.13.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working P1 question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants