【问题标题】:Getting 'The token contains no permissions, or permissions can not be understood' in daemon flow office365在守护程序流office365中获取“令牌不包含权限,或权限无法理解”
【发布时间】:2016-09-29 20:29:40
【问题描述】:

我在阅读所有用户日历时遇到问题,我在此解释过:Using Microsoft graph to read all users calendars

根据文档,这是可用的,但它不起作用,回复是最好使用以下文章(守护程序或服务应用程序)中描述的流程。

https://blogs.msdn.microsoft.com/exchangedev/2015/01/21/building-daemon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow/

我做过的事情: - 我在 Azure 门户中的 Active Directory 下注册了我的 Web 应用程序。我将其设置为 Web 应用程序(不是本机客户端应用程序)。我将其设置为多租户并授予应用程序权限。 - 我制作了一个密钥,编辑了清单并上传了这个。

我正在做的是:

1) 获取用户的租户ID,此时admin用户给予权限。

2) 如文章中所述:我只使用我取回的tenantId,我没有对访问令牌做任何事情。

3) 然后我从https://login.windows.net/TENANT_ID/oauth2/token?api-version=1.0 获得一个令牌,这似乎也可以工作(经过大量搜索)。

4) 当我将访问令牌放回https://jwt.io 时,我得到了一个有效的结果(至少看起来是这样),请参见此处:https://www.evernote.com/shard/s29/sh/5128795e-e7fd-4b8e-a779-5795cd83a66d/6e67979e1b628b06da60a5dcd5ba99a4

5) 无论我之后使用访问令牌提出什么请求,我都会得到:

The token contains no permissions, or permissions can not be understood.

这些是我在步骤 1 中要求的范围。

SCOPES = [ "openid" "Calendars.Read", "User.Read.All", "offline_access" ]

几个问题:

  • 我可以丢弃我在步骤 1 中返回的令牌并仅使用租户 ID 是否正常。此时用户收到一条消息,需要授权站点(使用范围......)。在第 3 步中,用户不再收到弹出窗口。如果我不使用我当时得到的令牌,它怎么能记住?
  • 我需要使用哪些端点?关于守护进程的帖子说 https://outlook.office365.com 但是当我在我的应用程序配置中的 Azure 活动目录中时,如果我单击 view endpoints,我会看到 https://graph.windows.net 按钮。
  • 在我收到的第一个问题的回复中:我们正在努力支持您请求的场景(访问其他用户的日历),但该功能尚未发布。请继续关注... 也许我需要等待,但有什么迹象表明什么时候?这是几天的事吗?周?

【问题讨论】:

  • 可以编辑您的问题并包含一些代码和/或您为每个步骤提出的请求。肯定会更容易找出发生了什么。

标签: office365 adal microsoft-graph-api azure-ad-graph-api


【解决方案1】:

基于博客,它首先请求 id 令牌。您使用的仅限应用程序令牌的请求是什么?端点https://login.windows.net/common/oauth2/token 是获取令牌的旧端点。

你可以参考下面的REST来获取app-only token(参考here):

POST: https://login.microsoftonline.com/o365e3w15.onmicrosoft.com/oauth2/token
grant_type=client_credentials&client_id={clientID}&client_secret={encodedSecret}&resource=https%3A%2F%2Fgraph.microsoft.com

然后我们可以通过下面的 REST 获取我们想要的用户日历:

GET: https://graph.microsoft.com/v1.0/users/user1@tenant.onmicrosoft.com/calendarview?startDateTime=2016-05-01T00:00:00&endDateTime=2016-06-01T08:00:00
authorization: bearer {token}

在上面的示例中,我使用 Microsoft Graph(https://graph.microsoft.com) 请求日历,这是来自 Microsoft 云服务的多个 API 的统一端点。如果您使用 Exchange REST 进行开发,您还可以使用 single canlenader endpoint https://outlook.office.com 替换令牌请求中的资源。

【讨论】:

  • 感谢您的回复:我使用 login.windows.net,因为它在博客中是这样解释的。只是为了确保它是我需要创建的守护程序应用程序,因为其他流程不允许我访问其他用户的日历(请参阅我链接的 SO 问题,他们建议我这样做)。您在此处解释的流程是正常流程,但如果管理员授予权限然后您查询其他日历,则该流程不起作用。
  • 上面的流程使用的是客户端凭证流程,该流程用于您需要的守护程序应用程序。有关此流程的详细信息,请参阅Service to Service Calls Using Client Credentials
  • 仅供参考:login.windows.net 确实是用于获取代码和令牌的旧端点,但仍然有效(通过直接访问 login.microsoftonline.com,您将为自己节省一个跳跃,但在功能上它们是相同的)。在 Azure 管理门户中,请求 application 权限 - 应用配置中的左侧权限列)。然后,您可能需要让管理员重新同意以获取为您的守护程序应用程序设置的权限,方法是将它们发送到授权端点(使用 prompt=consent)。同意后,您可以调用令牌端点。令牌中应该有“角色”声明。
【解决方案2】:

要将应用程序作为守护程序运行,您需要使用应用程序身份登录(使用 appid 和 appkey)。

资源:

"https://graph.microsoft.com/"

我正在使用用于 dotnet 的 ADAL 库(我相信您可以找到类似的东西),这是我的登录代码:

 public static AuthenticationResult LoginForDaemon(string InTenantName, string InClientId, string InClientAppKey, string InResourceId)
    {
        Check.Require(!string.IsNullOrEmpty(InTenantName), "InTenantName must be provided");
        Check.Require(!string.IsNullOrEmpty(InClientId), "InClientId must be provided");
        Check.Require(!string.IsNullOrEmpty(InClientAppKey), "InClientAppKey must be provided");
        Check.Require(!string.IsNullOrEmpty(InResourceId), "InResourceId must be provided");

        try
        {
            var clientCredential = new ClientCredential(InClientId, InClientAppKey);
            var authContext = new AuthenticationContext(string.Format(CultureInfo.InvariantCulture, @"https://login.microsoftonline.net/{0}/oauth2/logout", InTenantName));
            return authContext.AcquireToken(InResourceId, clientCredential);
        }
        catch (AdalSilentTokenAcquisitionException ex)
        {
            if (ex.Message.Contains("Failed to acquire token silently"))
                return null;
            else
                throw ex;
        }
    }

【讨论】:

    猜你喜欢
    • 2020-06-19
    • 2019-06-11
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多