Roe*_*and 8 c# oauth-2.0 office365 microsoft-graph-api
我正在使用 Microsoft Graph 并创建了一个应用程序来读取来自特定用户的邮件。
但是,在获得访问令牌并尝试读取邮件文件夹后,我收到了 401 未经授权的答复。详细信息是:
令牌不包含权限,或权限无法理解。
这似乎是一个非常明确的信息,但不幸的是我无法找到解决方案。这是我到目前为止所做的:
为其授予应用程序权限 Mail.Read、Mail.ReadWrite ( https://docs.microsoft.com/en-us/graph/api/user-list-mailfolders?view=graph-rest-1.0 )
Run Code Online (Sandbox Code Playgroud)// client_secret retrieved from secure storage (e.g. Key Vault) string tenant_id = "xxxx.onmicrosoft.com"; ConfidentialClientApplication client = new ConfidentialClientApplication( "..", $"https://login.microsoftonline.com/{tenant_id}/", "https://dummy.example.com", // Not used, can be any valid URI new ClientCredential(".."), null, // Not used for pure client credentials new TokenCache());
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
AuthenticationResult result = client.AcquireTokenForClientAsync(scopes).Result;
string token = result.AccessToken;
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。我确实得到了一个令牌。
现在我想阅读邮件文件夹:
Run Code Online (Sandbox Code Playgroud)url = "https://graph.microsoft.com/v1.0/users/{username}/mailFolders"; handler = (HttpWebRequest)WebRequest.Create(url); handler.Method = "GET"; handler.ContentType = "application/json"; handler.Headers.Add("Authorization", "Bearer " + token); response = (HttpWebResponse)handler.GetResponse(); using (StreamReader sr = new StreamReader(response.GetResponseStream())) { returnValue = sr.ReadToEnd(); }
这次我收到了 401 消息,其中包含详细信息:
令牌不包含权限,或者权限无法理解。
我在互联网上搜索过,但找不到我的令牌为什么没有权限的答案。
谢谢你的时间!
更新 1
如果我使用 Graph Explorer 读取邮件文件夹,则它工作正常。此外:如果我从我的浏览器中获取令牌 ID 在我的第二段代码中使用它,那么我也会得到一个结果。所以,问题实际上是我从第一步收到的令牌。
为了确保其按照您的预期工作,您应该明确说明您希望为哪个租户获取访问令牌。(在此租户中,应用程序当然应该已经获得管理员同意。)
使用特定于租户的端点,而不是“通用”令牌端点:
string url = "https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token";
Run Code Online (Sandbox Code Playgroud)
(其中{tenant-id}是租户的租户 ID(Guid)或任何经过验证的域名。)
我还强烈建议您不要自行构建令牌请求,正如您在问题中所示的那样。这对于教育目的可能有用,但从长远来看往往不安全且容易出错。
您可以使用各种库来代替。下面是使用适用于 .NET 的 Microsoft 身份验证库 (MSAL) 的示例:
// client_secret retrieved from secure storage (e.g. Key Vault)
string tenant_id = "contoso.onmicrosoft.com";
ConfidentialClientApplication client = new ConfidentialClientApplication(
client_id,
$"https://login.microsoftonline.com/{tenant_id}/",
"https://dummy.example.com", // Not used, can be any valid URI
new ClientCredential(client_secret),
null, // Not used for pure client credentials
new TokenCache());
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
AuthenticationResult result = client.AcquireTokenForClientAsync(scopes).Result
string token = result.AccessToken;
// ... use token
Run Code Online (Sandbox Code Playgroud)