图形 Api 身份验证在为具有身份验证作为应用程序的 CallRecords 创建订阅时失败

Graph Api Authentication failed on Creating Subscription for CallRecords with authentification as application

提问人:ingo_ww 提问时间:10/6/2021 最后编辑:ingo_ww 更新时间:11/10/2021 访问量:527

问:

我在客户星座中订阅callRecords时遇到问题,在那里我得到响应状态“禁止”(见帖子末尾)。

我做了这一步:

  1. 向 CallRecords.Read.All 注册 APp 注册并授予管理员同意
  2. 在尝试发送 POST 请求时,它在我的编码程序中都不起作用,但在 Postman 中,它可以使用应用程序权限。

它适用于 Postman,但不适用于 Azure Functions(本地启动)或其他编码的应用,并获取合适的持有者令牌。如果使用我从程序例程中获得的令牌发送 Post-request,我会收到 Forbidden 作为响应消息。

                HttpClient client = new HttpClient();
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri("https://login.microsoftonline.com/" + TenantId + "/oauth2/v2.0/token"));

                List<KeyValuePair<string, string>> parameters = new List<KeyValuePair<string, string>>();
                parameters.Add(new KeyValuePair<string, string>("client_id", ClientId));
                parameters.Add(new KeyValuePair<string, string>("scope", "https://graph.microsoft.com/.default"));
                parameters.Add(new KeyValuePair<string, string>("client_secret", ClientSecret));
                parameters.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
                request.Content = new FormUrlEncodedContent(parameters);

                HttpResponseMessage response = await client.SendAsync(request);
                string data = await response.Content.ReadAsStringAsync();
                Token = JsonConvert.DeserializeObject<TokenResponse>(data);

列表 1:获取访问令牌

我分析了我用 jwt.ms 获得的这个令牌(ID 和其他信息标有 ***)

  "typ": "JWT",
  "nonce": "***",
  "alg": "RS256",
  "x5t": "l3sQ-50cCH4xBVZLHTGwnSR7680",
  "kid": "l3sQ-50cCH4xBVZLHTGwnSR7680"
}.{
  "aud": "https://graph.microsoft.com",
  "iss": "https://sts.windows.net/***/",
  "iat": 1633425547,
  "nbf": 1633425547,
  "exp": 1633429447,
  "aio": "***",
  "app_displayname": "***",
  "appid": "***",
  "appidacr": "1",
  "idp": "https://sts.windows.net/***/",
  "idtyp": "app",
  "oid": "***",
  "rh": "***",
  "sub": "***",
  "tenant_region_scope": "EU",
  "tid": "***",
  "uti": "***",
  "ver": "1.0",
  "wids": [
    "0997a1d0-0d1d-4acb-b408-d5ca73121e90"
  ],
  "xms_tcdt": 1373376639
}.[Signature]

令牌的 JSON 信息

代码中的令牌与我从 postman-app 获取的令牌之间的区别是 SCP : “CallRecords.Read.All”

然后我发现,如果我使用具有委托权限 User.read.All 的应用程序注册,如果我在相关租户中登录了有效用户,则对我有用,则创建 callrecord-subscription 成功。 但是在客户端,我们只有一个应用程序注册+具有权限的密钥:callrecords.read.all 和 User.read.all。在客户案例中,我每次都在未经许可的情况下获得令牌。并且无法在租户中重定向到 postman callback-url。

我阅读了文档 https://learn.microsoft.com/de-de/graph/sdks/choose-authentication-providers?tabs=CS#client-credentials-provider 和相应的链接,但我没有得到我必须做什么的概述。

我也尝试了用于发送这篇文章的逻辑应用的 youtube 视频 https://www.youtube.com/watch?v=Z1xFjmttEvY - 步骤与客户应用注册创建类似。但它也失败了(同样的错误)。 我用 https://graph.microsoft.com/v1.0/subscriptions 身体:

{
    "resource": "/communications/callRecords",
    "changeType": "created",
    "clientState": "clientStateValue",
    "notificationUrl": " working URLendpoint>",
    "expirationDateTime": "2021-09-28T18:58:05.9125505Z",
    "latestSupportedTlsVersion": "v1_2"
}
{
  "error": {
    "code": "ExtensionError",
    "message": "Operation: Create; Exception: [Status Code: Forbidden; Reason: The request is not authorized for this user or application.]",
    "innerError": {
      "date": "2021-10-05T21:47:03",
      "request-id": "aa624900-02bb-4b06-92ba-755889b1f459",
      "client-request-id": "aa624900-02bb-4b06-92ba-755889b1f459"
    }
  }
}
BadRequest. Http request failed as there is an error getting AD OAuth token: 'AADSTS7000112: Application '***'(***-***-***-***-***) is disabled. Trace ID: ***-***-**-***-**Correlation ID: ***-***-***-***-***Timestamp: 2021-10-05 22:58:29Z'.

更新这发生了,但它不会伤害邮递员,Enable users to sign in它可以工作。为什么会这样,为什么我可以复制这种行为?

请有人告诉我做错了什么或我必须做什么,以便我可以像邮递员一样获得令牌,因为它作为应用程序请求?

microsoft-graph-api 访问令牌 更改通知

评论


答:

0赞 Danstan 10/6/2021 #1

您尝试添加的权限需要管理员同意。如果未同意/授予(如下面的屏幕截图所示),AAD 将忽略生成的访问令牌,而不使用角色声明。

enter image description here

若要获取包含声明的访问令牌,请确保已正确配置了两项内容。

  1. 确保为应用添加权限,并由管理员同意/授予应用的 Azure AAD 门户enter image description here
  2. 如果应用程序和用户位于不同的租户中,请确保应用程序在用户的租户中具有服务主体,并已添加和同意权限。

评论

0赞 ingo_ww 10/7/2021
谢谢!在第 1 点:我已经看到管理员同意已授予(如您的第 2 张屏幕截图所示)。第 2 点是问题所在,我不知道必要的步骤是什么。创建服务主体(powershell azure 门户)的方法有很多种,我没有找到具体的方法,如何做以及在哪里做。我计划使用函数应用(azure functions),因此必须为函数应用创建服务主体?我从来没有做过。而我们的此类管理工作的开发人员是临时的。
0赞 Danstan 10/7/2021
令牌获取中使用的是否是应用所属的租户 ID?TenantId
0赞 ingo_ww 10/7/2021
是的,我知道问题所在,我们有一个用于 outlook、团队和其他东西的租户,另一个用于 azure 资源。由此我知道了一个问题,即 callrecords- App Reg 必须在 teeams tenanat 中才能找到资源。是的,在客户上,我也使用客户租户 ID,但我被邀请加入租户,我们有权访问客户订阅,但没有应用注册权限。我们必须告诉他们我们需要什么,所以他们创建了 ann App Reg,在网络会议中,我告诉添加 Callrecords.Read.All 并授予管理员同意的步骤。但我在他们的租户中没有帐户。
0赞 Danstan 10/7/2021
你是对的。在这种情况下,最好的方法是将应用注册到与要进行身份验证的租户相同的租户中,并且该租户应该是呼叫记录所在的租户。
0赞 ingo_ww 10/7/2021
能否介绍如何为 azure 函数(函数应用)或逻辑应用创建服务主体的步骤,以便我可以将身份验证用作应用程序?你能告诉我我的用户需要什么角色和权限吗,否则我会问一个同事,告诉他他应该做什么。我认为要创建服务原则,在订阅和资源上需要非常高的权限。但是,如果我认识他们,我可以得到它在我们的租户中进行测试。因此,我可以直接对其进行测试,并说明必须在客户租户中执行哪些步骤。我希望你能帮助我。
0赞 ingo_ww 11/10/2021 #2

发布的问题仅通过无人值守撤销授予管理员同意而创建。

所以我会原谅这个帖子,因为通常没有理由。 由于无法查看/检查应用程序注册,我看不到撤销同意。

对于受访者的这种不必要的工作,我深表歉意。

所以一般来说,答案是正确的。