首页 > 解决方案 > “没有足够的权限来完成操作”,尽管授予了所有必要的权限

问题描述

{"odata.error":{"code":"Authorization_RequestDenied",
"message":
{"lang":"en","value":"Insufficient privileges to complete the operation."},
"requestId":"b205e5d0-f929-418e-9153-f1994e2c0893",
"date":"2020-02-15T06:53:57"}
}

我能够从服务器检索身份验证令牌并已通过 AAD 授予所有权限,但我仍然面临同样的问题。如果有人可以帮助我,那就太好了。我正在使用 Microsoft Graph API。

下面是我正在使用的代码

private const string clientID = "XXXX";
        private const string addInstance = "https://login.microsoftonline.com/{0}";
        private const string tenant = "XYZ";
        private const string resource = "https://graph.windows.net";
        private const string appKey = "appkey";
        static string authority = String.Format(CultureInfo.InvariantCulture, addInstance, tenant);

        private static HttpClient httpclient = new HttpClient();
        private static AuthenticationContext context = null;
        private static ClientCredential credential = null;


        static void Main(string[] args)
        {
            context = new AuthenticationContext(authority);
            credential = new ClientCredential(clientID,appKey);

            Task<string> token = GetToken();
            token.Wait();
            Console.WriteLine(token.Result);

            Task<string> users = GetUsers(token.Result);
            users.Wait();
            Console.WriteLine(users.Result);
            //Console.ReadLine();
        }

        private static async Task<string> GetUsers(string result)
        {
            string users = null;
            string queryString = "api-version=1.6";
            var uri = "https://graph.windows.net/ *The Microsoft 365 account assosciated with the tenant* /users?"+ queryString;
            httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result);
            var getResult = await httpclient.GetAsync(uri);
            if (getResult != null)
            {
                users = await getResult.Content.ReadAsStringAsync();
            }
            return users;
        }


        private static async Task<string> GetToken()
        {
            AuthenticationResult result = null;
            string token = null;
            result = await context.AcquireTokenAsync(resource, credential);
            token = result.AccessToken;
            return token;
        }
    }

标签: c#apiazure-active-directorymicrosoft-graph-api

解决方案


我已经尝试过以下方式并为我完美工作。

       //Token Request End Point
        string tokenUrl = $"https://login.microsoftonline.com/yourTenant.onmicrosoft.com/oauth2/token";
        var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);

        //I am Using client_credentials as It is mostly recommended
        tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
        {
            ["grant_type"] = "client_credentials",
            ["client_id"] = "b603c7be-a956_Your_Client_Id_a45996-e6921e61f36955",
            ["client_secret"] = "Vxf1SluKbgu4PF0loj_Your_Client_Secret_okjh8wL/yujh45lojhgg=",
            ["resource"] = "https://graph.windows.net" 
        });

        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);


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

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format("https://graph.windows.net/YourTenant.onmicrosoft.com/users?api-version=1.6"));

        //Passing Token For this Request
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", results.access_token);

        //Check The Response and extract response data
        HttpResponseMessage response = await _client.SendAsync(request);
        dynamic objGpraphUserList = JsonConvert.DeserializeObject<dynamic>(await response.Content.ReadAsStringAsync());

        return objGpraphUserList

使用的类:

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

我得到了预期的用户列表。请参阅屏幕截图。

在此处输入图像描述

验证您的令牌:

在https://jwt.io/上检查您的令牌,该令牌应该具有User.ReadWrite.AllUser.Read.All 应用程序权限

在此处输入图像描述

注意: 您应该具有以下权限Azure Active Directory Graph

在此处输入图像描述
更多信息请参考这个官方文档

希望这会有所帮助。


推荐阅读