获得';令牌不包含权限,或者权限无法理解';在后台进程流office365中

获得';令牌不包含权限,或者权限无法理解';在后台进程流office365中,office365,adal,microsoft-graph-api,azure-ad-graph-api,Office365,Adal,Microsoft Graph Api,Azure Ad Graph Api,我在阅读所有用户日历时遇到问题,我在此处解释: 根据文档,这是可用的,但是它不起作用,答案是最好使用下面文章(守护程序或服务应用程序)中描述的流 我所做的事情: -我在active directory下的Azure portal中注册了我的web应用程序。我将其设置为一个web应用程序(而不是本机客户端应用程序)。我将其设置为多租户,并授予应用程序权限。 -我制作了一个密钥,编辑了清单并上传了这个 我正在做的是: 1) 获取用户的租户ID,在此阶段管理员用户授予权限 2) 正如文章中所描述的:

我在阅读所有用户日历时遇到问题,我在此处解释:

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

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

我正在做的是:

1) 获取用户的租户ID,在此阶段管理员用户授予权限

2) 正如文章中所描述的:我只使用我得到的tenantId,我不使用访问令牌做任何事情

3) 然后,我从中得到一个令牌,它似乎也能工作(经过大量搜索)

4) 当我将我得到的访问令牌放回时,我得到了一个有效的结果(至少看起来是这样),请参见此处:

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

The token contains no permissions, or permissions can not be understood.
这些是我在步骤1中请求的范围

SCOPES = [ "openid" "Calendars.Read", "User.Read.All", "offline_access" ]
有几个问题:

  • 我可以扔掉在步骤1中得到的代币,只使用tenantId,这正常吗。此时,用户收到一条消息,需要授权站点(使用范围…)。在步骤3中,用户不再获得弹出窗口。如果我不使用我当时得到的代币,它怎么会记得
  • 我需要使用哪些端点?关于daemon的帖子说了,但当我在应用程序配置中的Azure active directory中时,如果我单击查看端点按钮,我会看到
  • 在我得到的第一个问题的回复中:我们正在努力支持您请求的场景(访问其他用户的日历),但该功能尚未发布。敬请期待。。。也许我需要等待,但有没有迹象表明什么时候?这是几天的事吗?几周

基于博客,它首先请求id令牌。对您正在使用的仅应用程序令牌的请求是什么?端点是获取令牌的旧端点

您可以参考下面的其余内容来获取仅应用程序令牌(请参阅):

然后,我们可以通过下面的其余部分获得所需用户的日历:

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()请求日历,日历是来自Microsoft云服务的多个API的统一端点。如果您是使用Exchange REST开发的,还可以在令牌请求中使用replace the资源。

要作为守护进程运行应用程序,您需要使用应用程序标识(使用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;
        }
    }

感谢您的回复:我使用了login.windows.net,因为它在博客中有这样的解释。只是为了确保它是我需要创建的守护程序应用,因为其他流不允许我访问其他用户的日历(请参阅我的链接SO问题,他们建议我这样做的地方)。您在此处解释的流程是正常流程,但如果管理员授予权限,然后您查询其他日历,则该流程不起作用。上面的流程使用的是客户端凭据流程,该流程用于守护程序应用程序,如您所需。有关此流的详细信息,请参阅。仅供参考:login.windows.net确实是代码和令牌获取的旧端点,但仍然有效(直接登录到login.microsoftonline.com可以节省一个跃点,但功能上它们是相同的)。在Azure管理门户中,请求应用程序权限(应用程序配置中左侧的权限列)。然后,您可能需要让管理员重新同意为您的守护程序应用程序设置权限,方法是将权限发送到授权端点(prompt=approve)。一旦同意,您就可以调用令牌端点。令牌中应包含“角色”声明。可以编辑您的问题,并包含一些代码和/或您针对每个步骤提出的请求。这肯定会让我们更容易发现到底发生了什么。
 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;
        }
    }