Azure B2C : Asp.Net Вызов веб-API Asp.Net Web.API

#c# #asp.net-web-api #azure-ad-b2c #msal

#c# #asp.net-web-api #azure-ad-b2c #msal

Вопрос:

У меня есть две службы веб-API (исходная и целевая). Все они зарегистрированы в Azure B2C как приложения AD с использованием клиентских секретов.

Я пытаюсь вызвать вызов gRPC API из исходной службы в API целевой службы, однако, когда я пытаюсь выполнить вызов, я получаю исключение gRPC, в котором говорится, что источник не прошел проверку подлинности.

Примечание: Когда я удаляю политику области действия и авторизованные атрибуты из целевого WebAPI, все работает нормально, но, конечно, это небезопасно.

При запуске исходной службы у меня есть следующее…

Примечание: настройки конфигурации верны как для источника, так и для цели. Я трижды проверил правильность всех настроек конфигурации.

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApi(options =>
    {
        Configuration.Bind("AzureAdB2C", options);
        options.TokenValidationParameters.NameClaimType = "name";
    },
    options =>
    {
        Configuration.Bind("AzureAdB2C", options);
    });
 

Я не уверен, требуется ли это, но я также включил следующую логику в запуск исходного API.

Примечание: на данный момент я жестко запрограммировал требуемые области.

 services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAdB2C")
    .EnableTokenAcquisitionToCallDownstreamApi(new string[] { "https://nextwaredev.onmicrosoft.com/nextware.productportal.sharedservices.api/sharedservices_readaccess", "https://nextwaredev.onmicrosoft.com/nextware.productportal.sharedservices.api/sharedservices_readwriteaccess" })
    .AddInMemoryTokenCaches();
 

Целевая служба имеет правильные политики, и обе службы настроены на использование авторизации и аутентификации..

 app.UseAuthentication();
app.UseAuthorization();
 

Я добавил разрешения API, которые требуются для источника, на основе тех же областей, указанных выше..

введите описание изображения здесь

Когда я пытаюсь вызвать метод в целевом API, я получаю обратно исключение gRPC, в котором говорится, что источник не прошел проверку подлинности.

Итак, я подумал, что, возможно, мне нужно передать токен доступа к приложению, однако, когда я пытаюсь получить токен доступа JWT (следуя этому примеру, вызывающему tokenAcquisition.GetAccessTokenForAppAsync) Я получаю другое исключение «AADB2C90086: предоставленный grant_type [client_credentials] не поддерживается».

Примечание: у меня есть приложение Blazor, у которого нет проблем с вызовом тех же защищенных API. Однако там я вызываю GetAccessTokenForUserAsync… который возвращает правильный токен с примененными областями, необходимыми для вызова тех же исходных или целевых служб веб-api.

Должен ли я включать AddMicrosoftIdentityWebAppAuthentication при запуске? Что еще я делаю не так?

Спасибо за вашу помощь! Приветствия

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

1. Не могли бы вы рассказать мне, как вы вызываете целевой API

Ответ №1:

Я не смог заставить поток учетных данных клиента работать с использованием Microsoft Identity Web Api непосредственно из Azure B2C, поэтому вместо этого я последовал этому превосходному руководству @Hossam Barakat по этой ссылке

Я закончил с двумя типами аутентификации, один из которых позволяет осуществлять связь с Web API => Web API с использованием Jwt Bearer, а другой используется Web APP => Web API, который использует

  • Элемент списка

Веб-api Microsoft Identity

         var authority = @"https://login.microsoftonline.com/"   Configuration["AzureAdB2C:TenantId"];
        var validIssuer = @"https://login.microsoftonline.com/"   Configuration["AzureAdB2C:TenantId"]   @"/v2.0";
        var audience = Configuration["AzureAdB2C:ClientId"];
        var validAudience = Configuration["AzureAdB2C:ClientId"];

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

        .AddJwtBearer("APIToAPI", options =>
           {
               options.Audience = audience;
               options.Authority = authority;
               options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
               {
                   ValidAudience = validAudience,
                   ValidIssuer = validIssuer
               };
           }
        )

        .AddMicrosoftIdentityWebApi(options =>
               {
                   Configuration.Bind("AzureAdB2C", options);
                   options.TokenValidationParameters.NameClaimType = "name";
               }
               , options =>
                {
                    Configuration.Bind("AzureAdB2C", options);
                },
                jwtBearerScheme: "AppToAPI"
        ); 
 

Затем, чтобы включить обе схемы, мне пришлось добавить следующее…

         services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().AddAuthenticationSchemes("APIToAPI", "APPToAPI").Build();
        }
 

Я также добавил следующий атрибут авторизации к действиям контроллера…

  [Authorize(AuthenticationSchemes = "APIToAPI, APPToAPI")]
 

Создание токена для каждого типа отличается.

Это то, что я использую для получения токена доступа для текущего пользователя, прошедшего проверку подлинности, в веб-приложении, вызывая API…

  private static string GetAccessTokenForUser(List<string> scopes)
    {
        if (scopes != null)
        {
            var container = ContainerLocator.Current.Container;

            var configuration = container.Resolve<IConfiguration>();

            var httpContextAccessor = container.Resolve<IHttpContextAccessor>();
            if (httpContextAccessor?.HttpContext?.User?.Identity?.IsAuthenticated ?? false)
            {
                var tokenService = httpContextAccessor.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>();
                try
                {
                    return Task.Run(() => tokenService.GetAccessTokenForUserAsync(scopes)).Resu<
                }
                catch (System.Exception ex)
                {
                    Log.Error(ex, "error while loading token for current user, try to login again");
                }
            }
        }
        return null;

    }
 

Это то, что я использую для получения токена доступа, когда это веб-API, вызывающий веб-API…

 public static async Task<TokenResponse> GetAccessTokenAsync(string scope)
    {
        var client = new HttpClient();
        var container = ContainerLocator.Current.Container;
        var configuration = container.Resolve<IConfiguration>();

        var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
        {
            Address = @"https://login.microsoftonline.com/"   configuration["AzureAdB2C:Domain"]  @"/oauth2/v2.0/token",
            ClientId = configuration["AzureAdB2C:ClientId"],
            ClientSecret = configuration["AzureAdB2C:ClientSecret"],
            Scope = scope
        });

        if (tokenResponse.IsError)
        {
            return null;
        }

        return tokenResponse;
    }
 

Если токен доступа получен, он просто добавляется в заголовок запроса перед вызовом метода gRPC и / или REST API.

Я надеюсь, что это поможет другим.

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

1. Привет. Вы нашли способ вернуть утверждения в токене доступа?

2. У вас есть репо для этого?