Использование Azure AD B2C для проверки подлинности blazor web api

#azure #blazor #azure-ad-b2c #msal

#лазурный #блейзор #azure-ad-b2c #msal

Вопрос:

Я следил за этой документацией по использованию Azure AD B2C для аутентификации в веб-приложении blazor https://docs.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/hosted-with-azure-active-directory-b2c?view=aspnetcore-5.0

Следуя этой документации, мы остаемся с решением, содержащим сервер и клиент, оба работают на https-порту 5001. Теперь я хотел бы переключиться на использование внешнего API, а не того, который работает на порту 5001.

Все кажется хорошим, и аутентификация проходит успешно при ручном использовании токена доступа, полученного blazor. Но blazor только автоматически присоединяет заголовки аутентификации к запросам, начинающимся с https://localhost:5001 .

Когда я вместо этого использую https://localhost:5003 , заголовок аутентификации остается пустым.

Есть ли что-то, что я могу добавить к параметрам поставщика моей MsalAuthentication, чтобы он мог передать этот токен доступа моему api, работающему на https://localhost:5003 ?

 builder.Services.AddHttpClient("{MyAssembly}.ServerAPI", client => client.BaseAddress = new Uri("https://localhost:5003"))
            .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("{MyAssembly}.ServerAPI"));

builder.Services.AddMsalAuthentication(options =>
{
    builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
    options.ProviderOptions.DefaultAccessTokenScopes.Add("https://{myproject}.onmicrosoft.com/e3b857b7-df50-4633-ae02-df4d4b20e911/API.Access openid offline_access");
});
 

Ответ №1:

Если вы хотите отправлять исходящие запросы к URI, которые не входят в базовый URI приложения, вы можете создать пользовательский AuthorizationMessageHandler класс для его реализации. Для получения более подробной информации, пожалуйста, обратитесь к here

Например

Создайте пользовательский класс AuthorizationMessageHandler

 using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

public class CustomAuthorizationMessageHandler : AuthorizationMessageHandler
{
    public CustomAuthorizationMessageHandler(IAccessTokenProvider provider,
        NavigationManager navigationManager)
        : base(provider, navigationManager)
    {
        ConfigureHandler(
            authorizedUrls: new[] { "https://localhost:44389/" },
            scopes: new[] { "https://<>.onmicrosoft.com/api/user_impersonation" });
    }
}
 

Добавьте следующий код Program.cs .

 using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace WebB2C
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("app");
          
            builder.Services.AddScoped<CustomAuthorizationMessageHandler>();
            builder.Services.AddHttpClient("ServerAPI", client =>
              client.BaseAddress = new Uri("https://localhost:44389/"))
                    .AddHttpMessageHandler<CustomAuthorizationMessageHandler>();
            builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
             .CreateClient("ServerAPI"));

            builder.Services.AddMsalAuthentication(options =>
            {
                builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
                options.ProviderOptions.DefaultAccessTokenScopes.Add("https://<>.onmicrosoft.com/api/user_impersonation");
                options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
                options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
            });

            await builder.Build().RunAsync();
        }
    }
}