Как мне вызвать веб-API от имени пользователя AAD, использующего требования безопасности? - PullRequest
0 голосов
/ 02 июня 2019

Итак, чтобы дать вам общий обзор того, чего я пытаюсь достичь, у меня есть веб-приложение, использующее аутентификацию AAD, и поэтому пользователям необходимо войти в учетную запись организации Microsoft, чтобы использовать большинство контроллеров.реализовано в веб-приложении (предназначенном для .NET Core).Visual Studio предлагает шаблон для этого типа настройки веб-приложения.Этот шаблонный проект, кажется, получает идентификацию пользователя как «ClaimsIdentity» (System.Security.Claims.ClaimsIdentity), что до сих пор нормально, пока пользователь проходит проверку подлинности AAD.У меня также есть решение .NET Core Web API, к которому веб-приложение должно обращаться от имени вошедшего в систему пользователя.Итак, у меня есть веб-приложение, которое регистрирует пользователя в AAD, а затем веб-API (который вызывает веб-приложение), у которого есть конечные точки контроллера, ожидающие запрос с проверкой подлинности AAD.Для того, чтобы это работало, я понимаю, что веб-приложение должно включать в себя подписанную идентификационную информацию, которую Microsoft (которая в данном случае является поставщиком безопасности) предоставила его, внутри заголовка запроса, который оно отправляет API.После этого API сможет просматривать заявки пользователей и действовать соответствующим образом.

Проблема здесь.В качестве заголовка я считаю, что мне нужно предоставить токен доступа, который Microsoft отправляет в веб-приложение ... однако я не могу найти этот токен.Все, что я могу извлечь из User или User.Identity, это претензии.Как я могу вызвать отдельный API от имени этих требований?Нужно ли полностью игнорировать шаблон, предоставленный Microsoft, и просто позвонить в конечную точку / token?Я просто хотел бы сделать это правильно:)

Это метод ConfigureServices в классе запуска веб-приложения:

public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureAD(options => Configuration.Bind("AzureAd", options));

        services.AddMvc(options =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

Здесь я хотел бы вызвать внешнюю сетьAPI от имени вошедшего в AAD для получения необходимых данных:

public IActionResult Index()
    {
        var user = User.Identity as ClaimsIdentity;

        var request = (HttpWebRequest)WebRequest.Create("http://localhost:4110/data");
        request.Headers["Authorization"] = "bearer " + getAccessToken_using_user;

        var response = (HttpWebResponse)request.GetResponse();

        var dataString = new StreamReader(response.GetResponseStream()).ReadToEnd();

        return View();
}

Конечно, я намерен заменить «getAccessToken_using_user» токеном доступа, который Microsoft предположительно предоставляет веб-приложению, как показано наих диаграмма .

1 Ответ

0 голосов
/ 02 июня 2019

Вы можете использовать MSAL для получения токена доступа для нижестоящего API.

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/on-behalf-of#practical-usage-of-obo-in-an-aspnet--aspnet-core-application

Это полный пример с потоком от имени:

https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/tree/master/2.%20Web%20API%20now%20calls%20Microsoft%20Graph

public static IServiceCollection AddProtectedApiCallsWebApis(this IServiceCollection services, IConfiguration configuration, IEnumerable<string> scopes)
{
 ...
 services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
 {
  options.Events.OnTokenValidated = async context =>
  {
   var tokenAcquisition = context.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>();
   context.Success();

   // Adds the token to the cache, and also handles the incremental consent and claim challenges
   tokenAcquisition.AddAccountToCacheFromJwt(context, scopes);
   await Task.FromResult(0);
  };
 });
 return services;
}
private async Task GetTodoList(bool isAppStarting)
{
 ...
 //
 // Get an access token to call the To Do service.
 //
 AuthenticationResult result = null;
 try
 {
  result = await _app.AcquireTokenSilent(Scopes, accounts.FirstOrDefault())
                     .ExecuteAsync()
                     .ConfigureAwait(false);
 }
...

// Once the token has been returned by MSAL, add it to the http authorization header, before making the call to access the To Do list service.
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

// Call the To Do list service.
HttpResponseMessage response = await _httpClient.GetAsync(TodoListBaseAddress + "/api/todolist");
...
}
...