AzureAD / microsoft-identity-web

Helps creating protected web apps and web APIs with Microsoft identity platform and Azure AD B2C

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GraphServiceClient - Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it (or one of its parent scopes) has already been disposed.

sam-wheat opened this issue · comments

Status Code: 0
Microsoft.Graph.ServiceException: Code: generalException
Message: An error occurred sending the request.

System.ObjectDisposedException: Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it (or one of its parent scopes) has already been disposed.
at Autofac.Core.Lifetime.LifetimeScope.ThrowDisposedException()
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable1 parameters, Object& instance) at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable1 parameters)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
at Microsoft.Identity.Web.TokenAcquisitionAspnetCoreHost.GetEffectiveAuthenticationScheme(String authenticationScheme)
at Microsoft.Identity.Web.TokenAcquisitionAspnetCoreHost.GetOptions(String authenticationScheme, String& effectiveAuthenticationScheme)
at Microsoft.Identity.Web.TokenAcquisition.GetAuthenticationResultForUserAsync(IEnumerable1 scopes, String authenticationScheme, String tenantId, String userFlow, ClaimsPrincipal user, TokenAcquisitionOptions tokenAcquisitionOptions) at Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(IEnumerable1 scopes, AuthorizationHeaderProviderOptions downstreamApiOptions, ClaimsPrincipal claimsPrincipal, CancellationToken cancellationToken)
at Microsoft.Identity.Web.TokenAcquisitionAuthenticationProvider.AuthenticateRequestAsync(HttpRequestMessage request)
at Microsoft.Graph.AuthenticationHandler.SendAsync(HttpRequestMessage httpRequestMessage, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Microsoft.Graph.HttpProvider.SendRequestAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at Microsoft.Graph.HttpProvider.SendRequestAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at Microsoft.Graph.HttpProvider.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at Microsoft.Graph.BaseRequest.SendRequestAsync(Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.BaseRequest.SendAsync[T](Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.UserRequest.GetAsync(CancellationToken cancellationToken)

Project

<ItemGroup>
  <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
  <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.4" />
  <PackageReference Include="MudBlazor" Version="6.15.0" />
  <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" NoWarn="NU1605" />
  <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.4" NoWarn="NU1605" />
  <PackageReference Include="Microsoft.Identity.Web" Version="2.18.1" />
  <PackageReference Include="Microsoft.Identity.Web.MicrosoftGraph" Version="2.18.1" />
  <PackageReference Include="Microsoft.Identity.Web.UI" Version="2.18.1" />	  
</ItemGroup>   

Config

"DownstreamApi": {
  /*
   'Scopes' contains space separated scopes of the Web API you want to call. This can be:
	- a scope for a V2 application (for instance api:b3682cc7-8b30-4bd2-aaba-080c6bf0fd31/access_as_user)
	- a scope corresponding to a V1 application (for instance <App ID URI>/.default, where  <App ID URI> is the
	  App ID URI of a legacy v1 Web application
	Applications are registered in the https:portal.azure.com portal.
  */
  "BaseUrl": "https://graph.microsoft.com/beta",
  "Scopes": "user.read"
},

Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddLogging(x => x.AddConsole().AddSerilog());
 
var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ');

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
	.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
	.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
	.AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
	.AddInMemoryTokenCaches();

builder.Services.AddControllersWithViews().AddMicrosoftIdentityUI();

builder.Services.AddAuthorization(options =>
{
	options.FallbackPolicy = options.DefaultPolicy;
});

builder.Services.AddScoped<AppAuthenticationProvider>();

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(ConfigureContainer);


// Add services to the container.   
builder.Services.AddExceptionHandler<ExHandler>();
builder.Services.AddRazorComponents(options => options.DetailedErrors = true)
	.AddInteractiveServerComponents();

builder.Services.AddControllersWithViews();
builder.Services.AddMudServices();
builder.Services.AddMessageBoxBlazor();
builder.Services.AddServerSideBlazor().AddMicrosoftIdentityConsentHandler();
builder.Services.AddScoped(x => BuildAppState(appConfig));

var app = builder.Build();


private static void ConfigureContainer(ContainerBuilder builder)
{
	string dir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), $"appsettings.{environmentName}.json");
	IEnumerable<IEndPointConfiguration> endPoints = EndPointUtilities.LoadEndPoints(dir);
	//builder.RegisterModule(new AutofacModule());
	RegistrationHelper registrationHelper = new RegistrationHelper(builder);

	registrationHelper
		.RegisterEndPoints(endPoints)
		.RegisterModule(new Dashboard.Services.AdaptiveClientModule());

	// Register ODBCHelper using first ERP Endpoint
	IEndPointConfiguration ep = endPoints.First(x => x.IsActive && x.API_Name == API_Name.MRP && x.EndPointType == EndPointType.DBMS);
	ILoggerFactory loggerFactory = new LoggerFactory();
	ILogger<ODBCSQLHelper> logger = loggerFactory.CreateLogger<ODBCSQLHelper>();
	ODBCSQLHelper odbchelper = new(ep.ConnectionString, logger);
	builder.RegisterInstance(odbchelper).SingleInstance();
	builder.RegisterModule(new Dashboard.Services.AutofacModule());
}

Page

@code {

	 [Inject] GraphServiceClient GraphServiceClient { get; set; }



	 protected override async Task OnInitializedAsync()
	 {
		 await base.OnInitializedAsync();
		 var usr = GraphServiceClient.Me.Request().GetAsync().Result; // Works
		 var user = await GraphServiceClient.Me.Request().GetAsync(); // Crash here
	 }
}

My page is called via navigation. None of my code is awaiting it. What am I doing wrong?

Related issues I have found through my research:

https://github.com/AzureAD/microsoft-identity-web/wiki/calling-graph

microsoftgraph/msgraph-sdk-dotnet#58

#1658

#1443

This issue replaces microsoftgraph/msgraph-sdk-dotnet#2472

Is is Blazor on .NET 8?

Yes, Blazor on .net 8.

When the code looks like it's not awaiting I think that's just what happens when the exception is thrown in Blazor in this situation.

The only thing I can see that's significantly different between your code and similar code I have working in some projects is that you're using AutoFac and I'm not.

As far as I know, AutoFac should be pulling in anything you registered earlier on like the GraphServiceClient but it might be worth ruling it out if you can easily comment out AutoFac temporarily and use the build in DI and see if the issue still occurs.