首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过Easy-Auth调用Azure Function App API支持从C#客户端使用Active Directory

如何通过Easy-Auth调用Azure Function App API支持从C#客户端使用Active Directory
EN

Stack Overflow用户
提问于 2019-06-13 04:55:04
回答 3查看 1.3K关注 0票数 4

我有一个配置了Azure Active Directory的Azure Function App,但是当我从我的客户端调用if时,我一直收到未经授权的响应。

代码语言:javascript
复制
                ///
                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);
                }

数据应该从函数App返回。

EN

回答 3

Stack Overflow用户

发布于 2019-06-13 23:12:25

对于client_credentials授权流,您的代码似乎没有什么不同。这里我给你提供了azure函数的精确示例。只需即插即用:)

示例包含:

  1. 如何使用client_credentials flow
  2. 获取令牌使用上述令牌

从Azure Active Directory租户获取用户列表

访问令牌类:

代码语言:javascript
复制
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; }

    }

要添加的引用:

代码语言:javascript
复制
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函数体:

代码语言:javascript
复制
  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. Permission类型:Application

你可以查看here。请看屏幕截图,以便更好地理解;确保在添加权限后,您已经单击了“为yourTenant授予管理员权限”。

Azure注意:这是你如何使用Azure函数访问Azure Active Directory令牌,之后如何使用该令牌高效地访问特定端点的资源。

票数 3
EN

Stack Overflow用户

发布于 2019-06-13 09:00:45

您确定您已经正确地实现了这一点吗?看起来您的一些参数对于客户端凭据流是错误的。请仔细检查您是否正确遵循客户端凭据流程。

客户端凭据授予流程记录如下: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/

票数 1
EN

Stack Overflow用户

发布于 2019-06-13 14:08:10

资源的值不正确。

{"resource", $"{ClientId}"}替换{"resource", "https://management.azure.com/"}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56570231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档