azure-active-directory - 使用应用程序 token 通过 REST API 调用 Microsoft Graph

标签 azure-active-directory microsoft-graph-api

我正在尝试使用 REST API 调用 Microsoft Graph,但遇到了一些问题。我的应用程序最终将成为部署到 Azure 的 Web 应用程序,我需要在没有登录用户的情况下通过 REST 调用 Graph。

在尝试调试时,我尝试制作最简单的应用程序。此应用程序只是尝试使用 Graph 从 Azure Active Directory 读取用户的个人资料。

我在 AAD 中注册了我的应用程序,所以我有一个租户、客户端 ID 和客户端 secret 。在这一点上,我已经在 AAD 和 Graph API 下授予了它所有权限(用于测试目的)。我可以从 AAD 获取 token ,但是当我使用此 token 调用 Graph API 时,我得到 401 - Unauthorized , 与 Access Token Validation Error .

我已经搜索了这个错误,但没有找到任何似乎适用的内容。

编辑:添加权限后,我还授予了我的应用程序的权限。

我从各种 sample 中抓取了一些碎片,试图让它发挥作用。这是代码:

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 - Unauthorized。

有没有人看到我做错了什么,或者我应该检查什么?

谢谢!

编辑:这是 token 中的 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"
}

最佳答案

查看您在问题中编辑的代码示例和访问 token 后,我可以指出一些问题:

  • 您获得的访问 token 不适用于调用 https://graph.microsoft.com .请注意 aud token 中的声明具有应用程序 ID 00000002-0000-0000-c000-000000000000这是 app id for the AAD Graph API ,这是一个相似但不同的端点。
  • 您拥有的 token 没有任何 role声明,用于授予对尝试在 App Only 流程中调用的客户端应用程序的访问权限。这可能是第一个问题的结果,修复您的资源还应该填充 role claim 。

  • 在查看您的代码以查看发生资源问题的位置时,我们可以看到您稍微混淆了 V1V2认证程序。

    您的代码似乎要遵循 V1 程序,因此您需要确保您的 POST获取 token 的请求具有以下参数:grant_type , client_id , client_secret , resource .

    在您的代码示例中,您似乎添加了 scope参数而不是 resource范围。这与V2方法一致,我们支持dynamic consent ,您可以在获取 token 时在其中定义所需的范围,但这不适用于 V1 端点。

    相反,您应该更新代码中的这两行:
    var resource = "https://graph.microsoft.com";

    requestParameters.Add("resource", resource);
    如果这有帮助,请告诉我。

    关于azure-active-directory - 使用应用程序 token 通过 REST API 调用 Microsoft Graph,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46614323/

    相关文章:

    azure - 微软图: Can I (re)use the user's Bearer Token forwarded by AAD in order to make "delegated" calls to the Graph API?

    angularjs - 读取其他用户时 Microsoft Graph api 403 访问被拒绝

    office365 - 微软office 365组: Guest user are unable to do drive call using graph endpoint

    azure-active-directory - 延迟更改带有证书的 Microsoft Graph 的 Azure AD 权限?

    asp.net-mvc - MVC 对 Office 365 AD 进行身份验证

    powershell - 如何以编程方式获取 Azure 订阅的所有成员

    powershell - Azure Active Directory 应用程序和服务主体

    azure - 连接到 Azure AD 条件访问 VPN 命令行

    microsoft-graph-api - Teams listChannel Graph API 导致 "Unauthorized error - "无法执行 Aad 后端请求 GetUsersByObjectIdsRequest”

    azure - 如何知道用户是否选择在 Azure B2C 中保持登录状态