当我具有访问令牌代码时,Authorization_RequestDenied

时间:2019-03-26 11:11:34

标签: c# webforms azure-active-directory

当我调用图形API时,访问令牌在访问令牌后出现Blockquote。

using (var webClient = new WebClient()) 
{
   var requestParameters = new NameValueCollection();
   requestParameters.Add("resource", resource);
   requestParameters.Add("client_id", clientID); 
   requestParameters.Add("grant_type", "client_credentials");
   requestParameters.Add("client_secret", secret);
   var url = $"https://login.microsoftonline.com/{tenant}/oauth2/token";
   var  responsebytes = await webClient.UploadValuesTaskAsync(url,"POST",requestParameters);
   var responsebody =Encoding.UTF8.GetString(responsebytes);
   var obj = JsonConvert.DeserializeObject<JObject>(responsebody);
   var token = obj["access_token"].Value<string>();
   access_token = token;  
}

当我请求表单后,通过这种方式从Azure AD获取用户列表

 public async Task<List<listItems>> GetData1( string token)
 {
     HttpClient http = new HttpClient(); 
     string query = "https://graph.microsoft.com/v1.0/users";
     HttpRequestMessage httpClient = new HttpRequestMessage(HttpMethod.Get, query);
     httpClient.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
     var res = await http.SendAsync(httpClient);
     var res1= await res.Content.ReadAsStringAsync();
     List<listItems> lstUsers = new List<listItems>();
     JObject results = JObject.Parse(res1); listItems itm;
      foreach (var Jelem in results["value"])
      { 
          string id = (string)Jelem["id"];
          string displayName = (string)Jelem["displayName"];
          itm = new listItems(); itm.id = id;
          itm.displayname = displayName; lstUsers.Add(itm);
      }
      return lstUsers;
 }

比我遇到“错误”:{ "code": "Authorization_RequestDenied", "message": "Insufficient privileges to complete the operation.", "innerError": { "request-id": "1ba8a3e3-7e27-4bad-affd-6929b9af3a9f", "date": "2019-03-26T10:56:26" }上面的错误

请帮助我解决此错误

1 个答案:

答案 0 :(得分:1)

原因

发生此问题的原因是应用程序没有访问用户信息所需的权限。因此,您需要为此请求分配必要的特权。

解决方案

要访问https://graph.microsoft.com/v1.0/users API,需要以下许可之一。

Permission type(从最低特权到最高特权)

  

委派的(工作或学校帐户)User.Read,User.ReadWrite,   User.ReadBasic.All,

     

User.Read.All,User.ReadWrite.All,Directory.Read.All,   Directory.ReadWrite.All,

     

Directory.AccessAsUser.All

     

委派的(个人Microsoft帐户)User.Read,User.ReadWrite

     

应用程序User.Read.All,User.ReadWrite.All,Directory.Read.All,

     

Directory.ReadWrite.All

请参见以下屏幕截图:

enter image description here

天蓝色门户出口

要在Azure门户上分配权限,请参见以下屏幕截图:

enter image description here

ASP.NET Web表单示例:

1。将新的Aspx页面添加到项目中

接受一个新的Web表单,在这里我将其作为Token.aspx并按如下所示设置其属性

 <%@ Page Language="C#" AutoEventWireup="true" Async="true"
 CodeBehind="Token.aspx.cs" Inherits="WebFormTest.Token" %>

2。从Nuget添加新参考

在您的项目参考中,从nuget软件包管理器控制台中添加一个新的服务参考,如下所示:

enter image description here

3。 Token.aspx.cs

Page_Load 方法的范围之外粘贴以下代码。一旦遇到丢失的引用错误,您可能需要在名称空间上添加以下引用。

  

使用System.Net.Http;

     

使用System.Net.Http.Headers;

class AccessToken
        {
            public string access_token { get; set; }
        }
        // Resource Owner Password Credentials Format
        private async Task<string> GetTokenByROPCFormat()
        {

            string tokenUrl = $"https://login.microsoftonline.com/YourTenantId/oauth2/token";
            var req = new HttpRequestMessage(HttpMethod.Post, tokenUrl);

            req.Content = new FormUrlEncodedContent(new Dictionary<string, string>
            {
                ["grant_type"] = "password",
                ["client_id"] = "ApplicationID",
                ["client_secret"] = "ApplicationSecret",
                ["resource"] = "https://graph.microsoft.com",
                ["username"] = "userEmailwithAccessPrivilege",
                ["password"] = "YourPassword"
            });

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

            var res = await client.SendAsync(req);

            json = await res.Content.ReadAsStringAsync();

            //Token Output
            results = JsonConvert.DeserializeObject<AccessToken>(json);
            Console.WriteLine(results.access_token);


            //New Block For Accessing Data from Microsoft Graph API
            HttpClient newClient = new HttpClient();

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me");

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", results.access_token);
            HttpResponseMessage response = await newClient.SendAsync(request);

            string output = await response.Content.ReadAsStringAsync();
            Console.WriteLine("Responsed data Is-\n\n" + output + "");
            return output;
        }

4。在Page_Load内调用GetTokenByROPCFormat()方法

现在在 Page_Load 内调用 GetTokenByROPCFormat ,如下所示

RegisterAsyncTask(new PageAsyncTask(GetTokenByROPCFormat));

5。令牌输出

如果您在 results 结果变量上设置调试器,则将获得令牌,如下所示

enter image description here

6。访问Microsoft Graph API

现在移至下一行并按如下所示设置调试器<​​/ p>

  

字符串输出=等待响应。Content.ReadAsStringAsync();

您将看到以下输出

enter image description here

希望它可以解决您的问题。谢谢。