Hi and thank you for your answer
My program.cs for the client:
builder.Services.AddHttpClient("ServerAPI",
client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("ServerAPI"));
builder.Services.AddGraphClient("https://graph.microsoft.com/User.Read");
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add(
"https://graph.microsoft.com/User.Read");
options.ProviderOptions.LoginMode = "redirect";
});
GraphClientExtensions.cs:
public static IServiceCollection AddGraphClient(
this IServiceCollection services, params string[] scopes)
{
services.Configure<RemoteAuthenticationOptions<MsalProviderOptions>>(
options =>
{
foreach (var scope in scopes)
{
options.ProviderOptions.AdditionalScopesToConsent.Add(scope);
}
});
services.AddScoped<IAuthenticationProvider,
NoOpGraphAuthenticationProvider>();
services.AddScoped<IHttpProvider, HttpClientHttpProvider>(sp =>
new HttpClientHttpProvider(new HttpClient()));
services.AddScoped(sp =>
{
return new GraphServiceClient(
sp.GetRequiredService<IAuthenticationProvider>(),
sp.GetRequiredService<IHttpProvider>());
});
return services;
}
private class NoOpGraphAuthenticationProvider : IAuthenticationProvider
{
public NoOpGraphAuthenticationProvider(IAccessTokenProvider tokenProvider)
{
TokenProvider = tokenProvider;
}
public IAccessTokenProvider TokenProvider { get; }
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
var result = await TokenProvider.RequestAccessToken(
new AccessTokenRequestOptions()
{
Scopes = new[] {"https://graph.microsoft.com/User.Read"}
});
if (result.TryGetToken(out var token))
{
request.Headers.Authorization ??= new AuthenticationHeaderValue(
"Bearer", token.Value);
}
}
}
private class HttpClientHttpProvider : IHttpProvider
{
private readonly HttpClient http;
public HttpClientHttpProvider(HttpClient http)
{
this.http = http;
}
public ISerializer Serializer { get; } = new Serializer();
public TimeSpan OverallTimeout { get; set; } = TimeSpan.FromSeconds(300);
public void Dispose()
{
}
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
{
return http.SendAsync(request);
}
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
HttpCompletionOption completionOption,
CancellationToken cancellationToken)
{
return http.SendAsync(request, completionOption, cancellationToken);
}
}