簡體   English   中英

如何設置 Azure 應用程序的權限,以便應用程序可以訪問站點及其驅動器?

[英]How do I set up permissions for an Azure Application so that an application can access a site and its drives?

第一次使用 Microsoft Graph API 時遇到了一些我不太確定的問題。

我應該構建一些概念證明 web 應用程序,我基本上可以從應用程序(具有自己的身份)查看業務驅動器(或站點/組驅動器)並將文件上傳/下載到它。 但是,我在弄清楚我做錯了什么時遇到了一些問題。

我寫了一些輔助函數來幫助我獲取令牌,但它似乎不起作用。

以下是我寫的函數:

public static async Task<string> GetAccessToken() {

    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(tokenUrl);
        // We want the response to be JSON.
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        // Build up the data to POST.
        List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
        postData.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
        postData.Add(new KeyValuePair<string, string>("client_id", clientId));
        postData.Add(new KeyValuePair<string, string>("client_secret", clientSecret));
        postData.Add(new KeyValuePair<string, string>("scope", scope));
        FormUrlEncodedContent requestBody = new FormUrlEncodedContent(postData);
        //Request Token
        var request = await client.PostAsync(tokenUrl, requestBody).ConfigureAwait(false);
        var response = await request.Content.ReadAsStringAsync();
        var responseData = JsonConvert.DeserializeObject(response);
        //Return Token
        return ((dynamic)responseData).access_token;
    }
}

public static async Task<dynamic> GetSite(string accessToken) {

    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(baseUrl);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        // Add the Authorization header with the AccessToken.
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
        // create the URL string.
        string url = string.Format("{0}sites/root/", baseUrl);
        // make the request
        HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
        // parse the response and return the data.
        string jsonString = await response.Content.ReadAsStringAsync();
        object responseData = JsonConvert.DeserializeObject(jsonString);
        return (dynamic)responseData;
    }
}

每當我嘗試獲取一個站點時,它似乎都無法正常工作。 所以我想我可以嘗試 Postman 中的請求,看看它們是否可以在那里工作,但是在為應用程序 API 調用設置 Postman之后,我通常會得到這樣的響應:

{
  "error": {
    "code": "generalException",
    "message": "An unspecified error has occurred.",
    "innerError": {
      "date": "SomeTimeLateAtNight",
      "request-id": "WhateverTheRequestIDis",
      "client-request-id": "WhateverTheClientRequestIDis"
    }
  }
}

我在這里做錯了嗎? 在我的應用程序注冊中,我將 API 權限設置為"Sites.ReadAll, Sites.ReadWriteAll" ,這是我從這里找到的。 我通過jwt.ms運行我的令牌,發現我的角色設置為:

"APIConnectors.ReadWrite.All", "Sites.Selected", "Directory.ReadWrite.All", "Sites.Read.All", "Sites.ReadWrite.All", "Sites.Manage.All", "Files.ReadWrite.All", "Directory.Read.All", "Files.Read.All", "APIConnectors.Read.All", "Sites.FullControl.All"

這些應該是我需要讀/寫/查看這些的嗎? 所以我有點困惑。

只是為了好玩,我嘗試通過Microsoft Graph Explorer完成我的請求,但一切都按預期工作。 我還從我所做的 Graph Explorer 請求中提取了身份驗證令牌,並將其推入我的 Postman 請求中,它最終工作了,這讓我相信我用 Azure 應用程序 ZDB974238714CA8DE634ACE 權限搞砸了一些東西。 關於從這里到 go 的任何建議? 不確定我是否解釋得足夠清楚,但我應該如何解決它,以便應用程序的請求獲得實際結果,而不是我得到的一般異常? (因為應用程序會自行下載/上傳,無需任何其他用戶登錄。)

我為您的代碼創建了一個新的 Azure AD 應用程序以進行快速測試,這些是我授予我的應用程序的權限,請確保您已單擊“授予管理員同意”按鈕以完成授予權限過程:

在此處輸入圖像描述

下面是我的測試代碼,基於控制台應用程序:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace GraphAPITest
{
    class Program
    {
        static void Main(string[] args)
        {
            var accessToken = GetAccessToken().GetAwaiter().GetResult();
            Console.WriteLine(GetSite(accessToken).GetAwaiter().GetResult());
        }



        public static async Task<string> GetAccessToken()
        {

            using (var client = new HttpClient())
            {
                var clientId = "<app id>"; 
                var clientSecret = "<secret>";
                var tenant = "<your tenant name/id>";

                var scope = @"https://graph.microsoft.com/.default";
                var tokenUrl = @"https://login.microsoftonline.com/"+ tenant + "/oauth2/v2.0/token";
                client.BaseAddress = new Uri(tokenUrl);
                // We want the response to be JSON.
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                // Build up the data to POST.
                List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
                postData.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
                postData.Add(new KeyValuePair<string, string>("client_id", clientId));
                postData.Add(new KeyValuePair<string, string>("client_secret", clientSecret));
                postData.Add(new KeyValuePair<string, string>("scope", scope));
                FormUrlEncodedContent requestBody = new FormUrlEncodedContent(postData);
                //Request Token
                var request = await client.PostAsync(tokenUrl, requestBody).ConfigureAwait(false);
                var response = await request.Content.ReadAsStringAsync();
                var responseData = JsonConvert.DeserializeObject(response);
                //Return Token
                return ((dynamic)responseData).access_token;
            }
        }

        public static async Task<dynamic> GetSite(string accessToken)
        {

            using (var client = new HttpClient())
            {
                var baseUrl = "https://graph.microsoft.com/v1.0/";
                client.BaseAddress = new Uri(baseUrl);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                // Add the Authorization header with the AccessToken.
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
                // create the URL string.
                string url = string.Format("{0}sites/root/", baseUrl);
                 

   // make the request
                HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
                // parse the response and return the data.
                string jsonString = await response.Content.ReadAsStringAsync();
                object responseData = JsonConvert.DeserializeObject(jsonString);
                return (dynamic)responseData;
            }
        }
    }

    
}

結果:

在此處輸入圖像描述

如果您還有其他問題,請告訴我。

檢查權限類型應用程序或委托。

在此處輸入圖像描述

如果是應用權限,相應權限的狀態欄 - 綠色

在此處輸入圖像描述

如果您看到警告消息 - 表示尚未授予管理員同意。 在使用該應用程序之前,您必須獲得同意。 這個錯誤很可能就是這種情況。

您可能已添加必要的權限,但忘記提供 Satya 確定的“管理員同意”。 另外,我建議使用 Microsoft 的 MSAL 庫來處理此流程,例如https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-netcore-daemon可讀的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM