当前位置: 首页 > 知识库问答 >
问题:

无法为守护程序应用程序使用OAuth2认证Microsoft 365电子邮件

蒋俊人
2023-03-14

我正在构建守护程序应用程序,这些应用程序读取邮箱并将票证问题转换为我们的应用程序。此应用程序将使用OAuth2通过IMAP/POP3协议连接到M365邮件服务器进行身份验证。我使用MailKit获取电子邮件。默认情况下,它支持OAuth2。它只需要访问令牌作为密码替换。我做了什么

使用此指南注册应用程序。具有以下详细信息

  • 我选择生成客户端密码而不是使用证书

其余的不变。

using Microsoft.Identity.Client;
using MailKit;
using MailKit.Search;
using MailKit.Security;

const string clientSecret = "xxx";
const string clientId = "yyy";
const string tenant = "zzz";
const string graphApi = "https://graph.microsoft.com/";
const string mailApi = "https://outlook.office.com/";

var apiClient = ConfidentialClientApplicationBuilder.Create(clientId)
    .WithClientSecret(clientSecret)
    .WithAuthority(new System.Uri($"https://login.microsoftonline.com/{tenant}"))
    .Build();
string[] scopes = new[]
{
//    $"{graphApi}.default",

// based on docs: https://docs.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth
//    $"{mailApi}IMAP.AccessAsUser.All",
//    $"{mailApi}POP.AccessAsUser.All",

// based on URI generated when adding permission
//    "https://outlook.office365.com/Mail.ReadWrite",

// trying to guess
//    $"{graphApi}.Mail.ReadWrite",
//    $"{graphApi}/Mail.ReadWrite",
};
var result = await apiClient.AcquireTokenForClient(scopes).ExecuteAsync();
using (var mailClient = new MailKit.Net.Imap.ImapClient())
{
    await mailClient.ConnectAsync("outlook.office365.com", 993, true);
    var auth = new SaslMechanismOAuth2($"user.domain@mytenant.onmicrosoft.com", result.AccessToken);
    await mailClient.AuthenticateAsync(auth);
    var mailBox = await mailClient.GetFolderAsync("INBOX");
    await mailBox.OpenAsync(FolderAccess.ReadWrite);
    var ids = await mailBox.SearchAsync(SearchQuery.All);
    foreach (var id in ids)
    {
        var message = await mailBox.GetMessageAsync(id);
        //message.Dump();
    }
}

我尝试了不同类型的作用域,结果如下:

  1. 使用$“{graphApi}时获取的令牌。默认值”,但邮件身份验证失败

任何帮助都将不胜感激。这是原始MS docs repo中的问题副本。

共有1个答案

萧晔
2023-03-14

不是100%确定这适用于您的场景,但这里是:

我们面临着同样的问题(因此偶然发现了您的帖子),并首先使用不同的流程来请求令牌来解决它。除了client_idclient_secret之外,我们还为我们要访问的邮箱用户提供了密码身份验证的所有详细信息:

POST https://login.microsoftonline.com/[your tenantid]/oauth2/v2.0/token

grant_type=password
username=[username for mailbox]
password=[password for that user]
client_id=[application client id]
client_secret=[application_client_secret]
scope=https://outlook.office365.com/IMAP.AccessAsUser.All openid offline_access

(跳过所有编码,添加换行符等)

然后,连接到IMAP outlook。office365.com,用户[邮箱用户名]使用XOAUTH2,接收到的令牌可以无缝工作。

 类似资料:
  • 任务清理(类型:Delete){Delete RootProject.BuildDir}

  • 我有几个Azure Functions,我想使用Azure AD对其应用身份验证。在用户模拟身份验证方面,我已经成功做到了这一点。但不幸的是,我无法从尝试访问Azure Functions的守护程序应用程序中获得同样的工作。 我的守护程序应用程序在Azure AD中注册,并公开应用程序范围。基本上,我有其他构建为应用程序服务的API,可以从守护程序应用程序成功地进行身份验证。我为Azure功能应用

  • 我有一个Azure Function应用程序,运行在使用Azure AD B2C进行身份验证的高级计划中。简单SPA的用户通过广告B2C的登录流获得他们的代币。SPA在AD B2C中注册为应用程序,功能应用程序的身份验证配置为使用该应用程序注册: 身份验证/Azure Active Directory/高级 ClientId:<代码> 颁发者Url:<代码>https:// 使用通过SPA获得的这

  • 本文向大家介绍gradle 使用Gradle守护程序,包括了gradle 使用Gradle守护程序的使用技巧和注意事项,需要的朋友参考一下 示例 您可以启用Gradle守护程序来改善构建的性能。 Gradle守护程序使Gradle Framework保持初始化和运行状态,并在内存中缓存项目数据以提高性能。 对于单个版本 要为单个构建启用守护程序,您只需将--daemon参数传递给gradle命令或

  • 问题内容: 我有一个使用Flask用Python编写的小应用程序。现在,我正在nohup下运行它,但是我想使其守护进程。这样做的正确方法是什么? 问题答案: 使用gunicorn部署可能是最简单的方法,请先安装gunicorn,然后: 尽管你可能想使用主管或类似性质的工具来监视黑胶皮(at the very least use – so you can reload/stop gunicorn e

  • 问题内容: 如何使Callable线程成为守护线程? 这是我正在尝试的。我正在尝试执行一组线程,其中一个线程未完成而进入无限循环。它执行的是程序的主线程不会终止,即使所有代码语句都已执行。之后主线程进入挂起模式。 这是相同的代码段。 主程序 问题答案: 如何使Callable线程成为守护线程? 您需要使用新的创建守护程序线程。在这里查看此答案:Java中的执行器和守护程序 默认情况下,执行者在构建