访问令牌不包含通过 Microsoft Graph 声明的 SCP(角色)

Access token not containing SCP (roles) claims via Microsoft Graph

我正在使用 Microsoft Graph SDK 为我的应用程序(不是用户)获取访问令牌,以便从共享点读取。我一直在关注这个 document, as well as posted this 。链接的 SO 中的代码是相同的。我能够在 Azure 门户中添加应用程序权限并授予它们(通过按下按钮)。问题是,返回使用的令牌中不包含任何角色/scp 声明。因此,在使用令牌时,我收到 "Either scp or roles claim need to be present in the token" 消息。

可以肯定的是,我在获取访问令牌时传递的范围的唯一值是:https://graph.microsoft.com/.default。我没有传递 Sites.ReadWrite.All 之类的任何其他内容(如果我仍然添加该范围,我会得到一个例外)。我不确定如何继续进行故障排除,如有任何帮助,我们将不胜感激。

编辑:使用如下所示的图形 SDK 添加了代码:

var client = new ConfidentialClientApplication(id, uri, cred, null, new SessionTokenCache());
var authResult = await client.AcquireTokenForClientAsync(new[] {"https://graph.microsoft.com/.default"});
var token = authResult.AccessToken;
var graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(async request => {request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token)}));
var drives = await graphServiceClient.Sites[<sharepoint_host>].SiteWithPath(<known_path>).Drives.Request().GetAsync(); 

The problem is, the token that comes back to be used does not contain any roles / scp claims in it.

如果您在 decoded 访问令牌中找不到任何 roles/scp 声明。您需要再次检查 Azure 门户中的权限。

解码后的访问令牌应包含您授予的角色。

登录 Azure 门户->单击 Azure Active Directory->单击应用程序注册(预览)->找到您的应用程序。

单击您的应用程序->API 权限->检查您是否已授予管理员同意您的应用程序。如果没有,请单击 'Grant admin consent'。

获取访问令牌的代码。您可以找到更多详细信息 here.

    //authority=https://login.microsoftonline.com/{tenant}/
    ClientCredential clientCredentials;
    clientCredentials = new ClientCredential("{clientSecret}");
    var app = new ConfidentialClientApplication("{clientId}", "{authority}", "{redirecturl}",
                                    clientCredentials, null, new TokenCache());
    string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
    AuthenticationResult result = null;
    result =  app.AcquireTokenForClientAsync(scopes).Result;
    Console.WriteLine(result.AccessToken);

似乎以不同的方式进行应用程序初始化是解决方案。而不是这个:

var client = new ConfidentialClientApplication(id, uri, cred, null, new SessionTokenCache());

这样做:

var app = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, credentials, null, new TokenCache());