c# – 身份验证令牌没有注册级别访问权限

背景

我正在对Microsoft的Azure消费端点进行一次宁静的API调用,详情如下.

https://docs.microsoft.com/en-gb/rest/api/consumption/reservationrecommendations/list

但是我总是会遇到以下错误.

Authentication token doesn’t have enrollment level access.

{
  "error": {
    "code": "401",
    "message": "Authentication token doesn't have enrollment level access. 
  }
}

令牌有效,可用于访问使用API​​下的其他端点. Azure页面上的“试用”测试链接实际上返回200,但是当我拨打电话时,我得到401.

任何人都可以对此错误消息有所了解吗?我无法在任何地方找到任何有关此错误的帮助.

认证

https://docs.microsoft.com/en-gb/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#first-case-access-token-request-with-a-shared-secret

 private static string GetAccessToken(string clientId, string clientSecret, string tenantId)
    {

        HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json;");

        string hostname = $"https://login.microsoftonline.com/{tenantId}/oauth2/token";

        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("grant_type", "client_credentials"),
            new KeyValuePair<string, string>("client_id", clientId),
            new KeyValuePair<string, string>("client_secret", clientSecret),
            new KeyValuePair<string, string>("resource", "https://management.azure.com/")
        });

        HttpResponseMessage httpResponse = client.PostAsync(hostname, content).Result;
        var responseString = httpResponse.Content.ReadAsStringAsync();

        if (httpResponse.StatusCode == HttpStatusCode.OK)
        {
            dynamic tokenObject = JsonConvert.DeserializeObject(responseString.Result);

            return tokenObject.access_token;
        }
        else
        {
            return null;
        }
    }

API调用

 public static dynamic GetReservationRecommendations(Params parameters)
 {
   var token = GetAccessToken(parameters.ClientId, parameters.ClientSecret, parameters.TenantId);

     HttpClient client = new HttpClient();
     client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
     client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json;");

     string hostname = $"https://management.azure.com/subscriptions/{parameters.SubscriptionId}/providers/Microsoft.Consumption/reservationRecommendations?api-version=2018-10-01";

     HttpResponseMessage httpResponse = client.GetAsync(hostname).Result;
     var responseString = httpResponse.Content.ReadAsStringAsync();

     if (httpResponse.StatusCode == HttpStatusCode.OK)
     {
         return responseString.Result;
     }
     else
     {
         return null;
     }
 }

最佳答案 推理错误

您用于获取令牌的应用程序标识对Consumer API – Reservation Recommendations List没有足够的权限

尝试测试链接工作但代码没有

AFAIK试用链接会要求您先在浏览器中使用帐户登录.因此它利用了用户身份而不是应用程序身份.因此,您正在测试的用户可能具有足够高的权限/角色,但代码当然是使用clientId和clientSecret,因此除非应用程序获得所有必需的权限,否则它仍然会失败.

所需权限

>此API使用ARM权限,因此需要为您的应用程序服务主体授予权限.至少“成本管理读者”的角色. (您可能已经完成了这些,因为您提到了一些其他适用于您的端点)

在Azure门户中,转到订阅>您的订阅>我是

《c# – 身份验证令牌没有注册级别访问权限》

然后为应用程序的服务主体添加角色分配

《c# – 身份验证令牌没有注册级别访问权限》
>查看错误消息“身份验证令牌没有注册级别访问权限.”,我认为您的Azure订阅属于EA(即企业协议).我这样说是因为我能够在EA订阅中重新生成完全相同的错误消息,而不是在另一个常规的即用即付订阅中,当服务主体已经具有“成本管理读者”角色时.如果您的订阅是在EA下,那么也请按照进一步的步骤操作.

因此,需要在Azure门户和企业门户(EA门户)中授予权限.有关详细信息,请查看此Microsoft文档. Assign access to Cost Management data

《c# – 身份验证令牌没有注册级别访问权限》

《c# – 身份验证令牌没有注册级别访问权限》

请按照此文档了解EA门户相关步骤. Enable access to costs in the EA portal
《c# – 身份验证令牌没有注册级别访问权限》

点赞