【问题标题】:Using Delegated Permissions from Daemon that uses Microsoft Graph使用来自使用 Microsoft Graph 的守护程序的委派权限
【发布时间】:2017-07-28 05:21:15
【问题描述】:

我有一个守护程序可以访问一些用户的电子邮件以便自动转发它们。我在 Azure 中注册了守护进程并请求了一些由管理员授予的应用程序权限。 然后我能够获得一个 oAuth2 令牌,并且应用程序按预期运行。

现在我的 IT 部门询问我,该应用是否可以模拟单个用户,而不是对每个邮箱拥有完全权限,以便守护程序只能读取和转发该用户的电子邮件。

所以我在 Azure 上注册了另一个应用程序,并且只为其请求了委派权限(我选择了所有不需要管理员批准的委派权限,总共 44 个)。 然后我构建了我的授权 URL 并将其发送给相关用户。用户单击该链接后,会看到应用程序请求的所有权限的列表,并同意将这些权限授予应用程序。

然后我的应用收到了一个授权码,正如预期的那样。 MS documentation 然后声明我可以使用该代码获取访问用户邮箱的令牌。因此,我使用 MS 提供的说明构建了 REST 参数:

"grant_type=authorization_code" +
"&client_id={appID}+ 
"&client_secret={appSecret} + 
"&code={auth_code}+
"&redirect_uri={Same_Redirect_URI_used_when_obtaining_Authorization_Code} +
"&resource=https://graph.microsoft.com"    

我向授权 URL 发出包含此内容的 POST 请求,如文档中所述:

https://login.microsoftonline.com/{myTenantID}/oauth2/token

现在奇怪的是,一旦我的脚本运行 xhr.send(tmpSnd); 方法(其中 tmpSnd 包含上述 REST 参数),我立即得到一个 msxml3.dll: Access is denied error。至少,我预计该错误会作为 POST 响应的一部分返回,但我什至从未通过 send() 方法。

这是我用来获取 Token 的 JS 代码:

  this.getDelegatedToken = function(appEndPoint, appID, appSecret,auth_Code,appURI){
    var result=null;
    var GRAPH_URL_TOKEN = "https://login.microsoftonline.com/" + appEndPoint + "/oauth2/token";
    xhr.open("POST", GRAPH_URL_TOKEN, false);
    xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

    var params ="grant_type=authorization_code" +
        "&client_id="     + appID + 
        "&client_secret=" + appSecret + 
        "&code="          + auth_Code+
        "&redirect_uri="  +appURI +
        "&resource=https://graph.microsoft.com";

    xhr.send(params);
    if(xhr.status==200) {
      result = JSON.parse(xhr.responseText);
    }
    return result;
  };

我想我在某处读到过,仅使用 Delegated Permissions 可能会导致守护进程出现问题,但对于我的一生,我不记得我在哪里读过它(使用 Graph 需要大量阅读!)。

编辑

如果我将 &code 参数设置为无效值,我会收到预期的错误消息(“代码格式错误或无效”)。如果我将其设置为之前已过期的授权码,我还会收到预期的错误消息(“提供的授权码或刷新码已过期”)。所以看起来我所有的 POST 参数都是有效的,因为当我故意传递一个无效的错误消息时,我会收到正确的错误消息。我只是不明白为什么,当我传递所有正确的参数时,我什至没有收到错误响应,我只收到来自 XHR 对象的 Access is denied 消息。

任何人都可以发现代码或流程中的任何明显错误吗?

【问题讨论】:

  • 你是从前端 JavaScript 运行的吗?
  • 我从 Windows Scripting Host 的应用内实例运行它。不涉及网络浏览器。应用程序本身作为 Windows 服务运行,这意味着不涉及 GUI。在某种程度上,它类似于 NodeJS 会做的事情。除了不是 NodeJS,它是一个 Windows 可执行文件(用 Delphi 编写),它实例化了 WSH。希望能回答你的问题。
  • 只是想确认您的tenantID(名为 appEndPoint 的变量)看起来像“contoso.com”(当然对于您的组织而言)。
  • 我已经尝试过使用 DNS (myprefix.myorg.com) 和 Azure 门户上显示的应用程序 ID。
  • 我希望您不要混淆 v2 API 和 v1 API。令牌和代码不能在 v2 和 v1 API 之间共享

标签: azure microsoft-graph-api


【解决方案1】:

获得授权码后,您需要对令牌端点进行 POST。见here

现在您已获得授权码并已获得授权 获得用户许可后,您可以将代码兑换为访问令牌以 所需资源,通过向/token 发送 POST 请求 端点:

// 换行只是为了便于阅读

POST /{tenant}/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=2d4d11a2-f814-46a7-890a-274a72a7309e
&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrqqf_ZT_p5uEAEJJ_nZ3UmphWygRNy2C3jJ239gV_DBnZ2syeg95Ki-374WHUP-i3yIhv5i-7KU2CEoPXwURQp6IVYMw-DjAOzn7C3JCu5wpngXmbZKtJdWmiBzHpcO2aICJPu1KvJrDLDP20chJBXzVYJtkfjviLNNW7l7Y3ydcHDsBRKZc3GuMQanmcghXPyoDg41g8XbwPudVh7uCmUponBQpIhbuffFP_tbV8SNzsPoFz9CLpBCZagJVXeqWoYMPe2dSsPiLO9Alf_YIe5zpi-zY4C3aLw5g9at35eZTfNd0gBRpR5ojkMIcZZ6IgAA
&redirect_uri=https%3A%2F%2Flocalhost%2Fmyapp%2F
&resource=https%3A%2F%2Fservice.contoso.com%2F
&client_secret=p@ssw0rd

//NOTE: client_secret only required for web apps

您在上面的代码中似乎没有正确执行此操作。让我知道这是否有帮助!

【讨论】:

  • 对不起,我在复制/粘贴我的代码时犯了错误...我现在已经在我的原始帖子中更正了它们。如您所见,我使用的值与 MS 文档中指定的值完全相同,但在调用 xhr.send() 方法时仍然出现相同的“访问被拒绝”错误(顺便说一下,xhr 是一个实例Microsoft.XMLHTTP)
【解决方案2】:

我假设,当您使用客户端密码时,您只会获得应用程序令牌。此令牌无法访问资源。要使用 App only 令牌访问资源,您需要 azure 门户上的应用权限(而不是委托)。添加应用程序权限检查,看看您是否仍然收到拒绝访问错误

【讨论】:

  • 正如我在最初的帖子中所解释的,我知道使用应用程序权限有效,但我的 IT 部门希望我使用委派权限,这就是我遇到麻烦的地方。
  • 您需要守护程序在用户帐户(委托)上运行。这不是矛盾吗。服务不会在每个用户帐户上运行。即使您制作任何网络挂钩(您可以在其中使用委托)并从你的守护进程调用,我想不出一种不涉及用户的方式来获取用户上下文。
  • 守护程序必须能够访问用户已授予权限的帐户。如果守护程序使用应用程序权限,那么它可以访问所有帐户,这是我的 IT 部门不喜欢的。守护程序有一个要监控的帐户列表,对于每个帐户,它必须能够检索然后转发消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多