Как вызвать API приложения-функции Azure с помощью Easy-Auth Включает использование Active Directory из клиента C # - PullRequest
4 голосов
/ 12 июня 2019

У меня настроено приложение-функция Azure с Azure Active Directory, но когда я звоню, если от моего клиента я получаю неавторизованный ответ.

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

                ///
                var @params2 = new NameValueCollection
                {
                    {"grant_type", "client_credentials"},
                    {"client_id", $"{ClientId}"},
                    {"client_secret", $"{ClientSecret}"},
                    {"username", userId},
                    {"resource", "https://management.azure.com/"}
                };
                var queryString2 = HttpUtility.ParseQueryString(string.Empty);
                queryString2.Add(@params2);
                var content = new FormUrlEncodedContent(new Dictionary<string, string>
                    {
                        {"grant_type", "client_credentials"},
                        {"client_id", ClientId},
                        {"client_secret", ClientSecret},
                        {"username", userId}
                    });
                var authorityUri2 = $"{string.Format(CultureInfo.InvariantCulture, AadInstance, Tenant).TrimEnd('/')}/oauth2/token";
                //var authorityUri2 = $"https://login.microsoftonline.com/{Tenant}/v2.0/.well-known/openid-configuration";
                var authUri2 = String.Format("{0}?{1}", authorityUri2, queryString2);
                var client2 = new HttpClient();
                var message = client2.PostAsync(authorityUri2, content).Result;
                //var message = client2.GetAsync(authorityUri2).Result;
                var response = message.Content.ReadAsStringAsync().Result;
                dynamic values=null;
                try
                {
                    values = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
                }
                catch
                {
                    values = response;
                }

                var AuthToken2 = values["access_token"];
                client2.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken2);
                HttpResponseMessage response2 = await client2.GetAsync(AppBaseAddress.TrimEnd('/') + "/api/AADIntegration");

if (response.IsSuccessStatusCode)
                {
                    // Read the response and data-bind to the GridView to display To Do items.
                    string s = await response.Content.ReadAsStringAsync();
                    log.LogInformation($"Success while getting / api / AADIntegration : {s}");

                    return (ActionResult)new OkObjectResult(s);
                }
                else
                {
                    string failureDescription = await response.Content.ReadAsStringAsync();
                    log.LogInformation($"An error occurred while getting / api / AADIntegration : {response.ReasonPhrase}\n {failureDescription}");
                    return (ActionResult)new OkObjectResult(failureDescription);
                }

Данные должны быть возвращены из приложения Function.

Ответы [ 3 ]

2 голосов
/ 13 июня 2019

Для client_credentials потока грантов ваш код кажется немного другим. Здесь я даю вам точный образец для лазурной функции. Просто подключи и играй :))

Пример содержит:

  1. Как получить токен, используя client_credentials flow
  2. Получение списка пользователей от Azure Active Directory арендатора, использующего выше лексема

Класс токена доступа:

public   class AccessTokenClass
    {
        public string token_type { get; set; }
        public string expires_in { get; set; }
        public string resource { get; set; }
        public string scope { get; set; }
        public string access_token { get; set; }

    }

Ссылка для добавления:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.Http;
using System.Collections.Generic;
using System.Net.Http.Headers;

Тело функции Azure:

  public static class FunctionGetUserList
    {
        [FunctionName("FunctionGetUserList")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {

            try
            {
                log.LogInformation("C# HTTP trigger function processed a request.");


                //Token Request endpoint Just replace yourTennantId/Name
                string tokenUrl = $"https://login.microsoftonline.com/yourTennantId/Name.onmicrosoft.com/oauth2/token";
                var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);

                tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
                {
                    ["grant_type"] = "client_credentials",
                    ["client_id"] = "b603c7bead87-Your_client_id-e6921e61f925",
                    ["client_secret"] = "Vxf1SluKbgu4P-Your_client_Secret-F0Nf3wE5oGl/2XDSeZ=",
                    ["resource"] = "https://graph.microsoft.com"
                });

                dynamic json;
                AccessTokenClass results = new AccessTokenClass();
                HttpClient client = new HttpClient();

                var tokenResponse = await client.SendAsync(tokenRequest);

                json = await tokenResponse.Content.ReadAsStringAsync();
                results = JsonConvert.DeserializeObject<AccessTokenClass>(json);
                var accessToken = results.access_token;

                //Create Request To Server
                using (HttpClient clientNew = new HttpClient())
                {

                    //Pass Token on header
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    //Get Data from API
                    var requestToAzureEndpoint = await client.GetAsync("https://graph.microsoft.com/v1.0/users");

                    if (requestToAzureEndpoint.IsSuccessStatusCode)
                    {
                        var result_string = await requestToAzureEndpoint.Content.ReadAsStringAsync();
                        dynamic responseResults = JsonConvert.DeserializeObject<dynamic>(result_string);

                        return new OkObjectResult(responseResults);

                    }
                    else
                    {
                        var result_string = await requestToAzureEndpoint.Content.ReadAsStringAsync();
                        return new OkObjectResult(result_string);
                    }
                }
            }
            catch (Exception ex)
            {

                return new OkObjectResult(ex.Message);
            }

        }


    }

Точка для запоминания:

Для доступа Azure Active Directory List users убедитесь, что вы иметь следующее разрешение:

  1. User.Read.All
  2. Тип разрешения: Application

Вы можете проверить здесь . Смотрите снимок экрана для лучшего понимания: Убедитесь, что вы нажали Grant admin consent for yourTenant после добавления разрешения.

enter image description here

Примечание: Вот как вы можете получить доступ к токену Azure Active Directory с помощью функции Azure после этого, как получить доступ к ресурсу с помощью этого эффективный токен для конкретной конечной точки API.

Если у вас все еще есть вопросы, не стесняйтесь поделиться Спасибо и счастливого кодирования!

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

Значение ресурса неверно.

Заменить {"resource", "https://management.azure.com/"} на {"resource", $"{ClientId}"}

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

Вы уверены, что правильно реализовали это? Похоже, что некоторые ваши параметры не соответствуют потоку учетных данных клиента. Пожалуйста, проверьте, правильно ли вы выполняете поток учетных данных клиента.

Поток предоставления учетных данных клиента задокументирован здесь: https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow

Но для получения дополнительной информации о том, как это правильно работает в вашем приложении функций, пожалуйста, обратитесь к блогу ниже для получения дополнительной информации / помощи по реализации этого. https://blogs.msdn.microsoft.com/ben/2018/11/07/client-app-calling-azure-function-with-aad/

...