背景
我正在对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.
题
任何人都可以对此错误消息有所了解吗?我无法在任何地方找到任何有关此错误的帮助.
码
认证
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门户中,转到订阅>您的订阅>我是
然后为应用程序的服务主体添加角色分配
>查看错误消息“身份验证令牌没有注册级别访问权限.”,我认为您的Azure订阅属于EA(即企业协议).我这样说是因为我能够在EA订阅中重新生成完全相同的错误消息,而不是在另一个常规的即用即付订阅中,当服务主体已经具有“成本管理读者”角色时.如果您的订阅是在EA下,那么也请按照进一步的步骤操作.
因此,需要在Azure门户和企业门户(EA门户)中授予权限.有关详细信息,请查看此Microsoft文档. Assign access to Cost Management data
请按照此文档了解EA门户相关步骤. Enable access to costs in the EA portal