Как обрабатывать токены для нескольких ресурсов в веб-сборке blazor MSAL

#blazor #msal #.net-5 #blazor-webassembly

Вопрос:

У меня есть приложение для веб-сборки .net5 blazor, настроенное с помощью msal auth для azure.

 services.AddMsalAuthentication(options =>
{
    configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
    options.ProviderOptions.DefaultAccessTokenScopes.Add("api://xxxxx/API.Access"); // API
    options.ProviderOptions.Cache.CacheLocation = "localStorage";
}); 
 

Это прекрасно работает.

Кроме того, мне нужно получить доступ к Microsoft graph. Я сделал это с помощью graph sdk и предоставил обработчик аутентификации для graph sdk

 public class GraphAuthenticationProvider : IAuthenticationProvider
{
    private readonly NavigationManager _navigationManager;

    public GraphAuthenticationProvider(IAccessTokenProvider tokenProvider, NavigationManager navigationManager)

    {
        TokenProvider = tokenProvider;
        _navigationManager = navigationManager;
    }

    public IAccessTokenProvider TokenProvider { get; }

    public async Task AuthenticateRequestAsync(HttpRequestMessage request)
    {
        string[] scopes = new[] { "https://graph.microsoft.com/Mail.ReadWrite", "https://graph.microsoft.com/Mail.Send" };

        var result = await TokenProvider.RequestAccessToken(
            new AccessTokenRequestOptions()
            {
                Scopes = scopes,
                ReturnUrl = _navigationManager.Uri
            });

        if (result.TryGetToken(out var token))
        {
            request.Headers.Authorization ??= new AuthenticationHeaderValue(
                "Bearer", token.Value);
        }
        else
        {
            _navigationManager.NavigateTo(result.RedirectUrl);
        }
    }
}
 

Похоже, что это можно сделать в соответствии с документацией, которую я смог найти, хотя, похоже, предполагается, что вы пытаетесь получить дополнительные области на том же ресурсе.
https://docs.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/additional-scenarios?view=aspnetcore-5.0#request-additional-access-tokens

С этим связаны две проблемы:

  • Я не могу найти способ сделать это с помощью всплывающего окна, что означает, что я вынужден перейти к перенаправлению, которое приводит к потере состояния программы. Это можно обойти, но, похоже, всплывающая версия согласия должна быть возможной?
  • Когда аутентификация завершается и я возвращаюсь в свое собственное приложение, оно пытается создать токен для всех областей, как для моего api, так и для графика, что, очевидно, приводит к сбою из-за нескольких ошибок ресурсов, что приводит меня к странице ошибок входа в систему. Несмотря на то, что на самом деле он правильно получил оба токена, и я могу просто уйти со страницы ошибки и получить доступ как к моему api, так и к графику.

Я не смог найти никакой документации для msal веб-сборки blazor с несколькими ресурсами. Может ли кто-нибудь объяснить, что я делаю неправильно, или указать мне на правильную документацию?

 public class GraphAuthorizationMessageHandler : AuthorizationMessageHandler
{
    public GraphAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigationManager)
        : base(provider, navigationManager)
    {
        ConfigureHandler(authorizedUrls: new[] { "https://graph.microsoft.com/" }, scopes: new[] { "https://graph.microsoft.com/Mail.ReadWrite", "https://graph.microsoft.com/Mail.Send" });
    }
}
 
 services.AddScoped<CustomAuthorizationMessageHandler>();
services.AddScoped<GraphAuthenticationProvider>();

services.AddScoped<GraphHttpProvider>();
services.AddScoped<GraphAuthorizationMessageHandler>();

services.AddHttpClient<GraphHttpProvider>(
    client => client.BaseAddress = new Uri("https://graph.microsoft.com"))
    .AddHttpMessageHandler<GraphAuthorizationMessageHandler>();

services.AddScoped(sp =>
     new GraphServiceClient(
        sp.GetRequiredService<GraphAuthenticationProvider>(),
        sp.GetRequiredService<GraphHttpProvider>())
);
 

Комментарии:

1. Вы видели этот учебник? docs.microsoft.com/en-us/graph/tutorials/blazor

2. @BrianParker В этом учебнике есть только один ресурс-api graph. Как бы я добавил в него свой собственный api, api://xxxxx/API.Access ?