我试图使用REST API调用Microsoft Graph,但我遇到了一些问题。我的应用程序最终将成为部署到Azure的Web应用程序,我需要在没有登录用户的情况下通过REST调用Graph。
在尝试调试时,我尝试制作最简单的应用程序。此应用只是尝试使用Graph从Azure Active Directory读取用户的配置文件。
我在AAD注册了我的应用,所以我有一个租户,客户ID和客户端密码。此时,我已根据AAD和Graph API(出于测试目的)给予它所有许可。我可以从AAD获取令牌,但是当我使用此令牌调用Graph API时,我得到401 - Unauthorized
,Access Token Validation Error
。
我已经搜索过这个错误,并且找不到任何似乎适用的内容。
编辑:我还在添加权限后授予我的应用权限。
我从各种样品中抓取了碎片以试图让它工作。这是代码:
var tenant = "tenant ID";
var clientID = "app ID";
// I've tried graph.microsoft.com and graph.microsoft.com/.default
var resource = "https://graph.microsoft.com/user.read.all";
var secret = "client secret";
string token;
using(var webClient = new WebClient())
{
var requestParameters = new NameValueCollection();
requestParameters.Add("scope", 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 jsonObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(responseBody);
token = jsonObject.Value<string>("access_token");
}
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
var response = await client.GetAsync(new Uri("https://graph.microsoft.com/v1.0/user/<user ID>"));
第二次电话回复401 - 未经授权。
有没有人看到我做错了什么,或者我应该检查一下?
谢谢!
编辑:这里是来自令牌的JSON,用Fiddler解码并删除了租户和客户ID:
{
"typ": "JWT",
"alg": "RS256",
"x5t": "HHByKU-0DqAqMZh6ZFPd2VWaOtg",
"kid": "HHByKU-0DqAqMZh6ZFPd2VWaOtg"
}
{
"aud": "spn:00000002-0000-0000-c000-000000000000",
"iss": "https://sts.windows.net/<tenant id>/",
"iat": 1507313785,
"nbf": 1507313785,
"exp": 1507317685,
"aio": "Y2VgYCguP8H/lUPs5seMpgeOze3vAA==",
"appid": "~client id~",
"appidacr": "1",
"idp": "https://sts.windows.net/~tenant id~/",
"oid": "37df6326-7ed1-4b88-a57c-b82319a5cb07",
"sub": "37df6326-7ed1-4b88-a57c-b82319a5cb07",
"tenant_region_scope": "NA",
"tid": "~tenant id~",
"uti": "IspHJJNqjUKWjvsWmXhDAA",
"ver": "1.0"
}
答案 0 :(得分:5)
在查看您编辑的代码示例和访问令牌之后,我可以指出一些问题:
https://graph.microsoft.com
。请注意,令牌中的aud
声明的应用ID 00000002-0000-0000-c000-000000000000
是app id for the AAD Graph API,它是一个类似但不同的端点。role
声明,这是用于授予对尝试在仅App流程中调用的客户端应用程序的访问权限的权限。这可能是第一个问题的结果,修复资源也应该填充role
声明。在查看代码以查看资源问题发生的位置时,我们可以看到您稍微混淆了V1和V2身份验证过程。
您的代码似乎想要遵循V1过程,因此您需要确保获取令牌的POST
请求具有以下参数:
grant_type
,client_id
,client_secret
,resource
。
在您的代码示例中,您似乎添加了scope
参数而不是resource
参数。这与我们支持dynamic consent的V2方法一致,您可以在其中定义获取令牌时所需的范围,但这不适用于V1端点。
相反,您应该在代码中更新这两行:
var resource = "https://graph.microsoft.com";
和
requestParameters.Add("resource", resource);
如果有帮助,请告诉我。
答案 1 :(得分:0)