使用无人参与的 C# 控制台验证 Office 365 IMAP 帐户

Authenticate Office 365 IMAP Account using Unattended C# Console

我正在开发需要对 Office 365 IMAP 帐户进行身份验证的 .NET Core 控制台应用程序 (C#)。目的是在无人值守的情况下检索邮件和处理 CSV 文件附件。

该应用已在 Azure 上注册为 Mobile/Desktop 应用,RedirectUri 设置为 http://localhost

以下代码会在 Chrome 网络浏览器中打开一个新选项卡,并要求提供用于登录的 Outlook 帐户。我需要阻止浏览器打开并完全从代码处理身份验证。

当前代码:

using var client = new ImapClient(new ProtocolLogger("imap.log"));

var options = new PublicClientApplicationOptions
{
    ClientId = _options.ClientId,
    TenantId = _options.TenantId,
    RedirectUri = "http://localhost"
};

var publicClientApplication = PublicClientApplicationBuilder
    .CreateWithApplicationOptions(options)
    .Build();

var scopes = new[]
{
    "email",
    "offline_access",
    "https://outlook.office.com/IMAP.AccessAsUser.All" // Only needed for IMAP
    //"https://outlook.office.com/POP.AccessAsUser.All",  // Only needed for POP
    //"https://outlook.office.com/SMTP.AccessAsUser.All", // Only needed for SMTP
};

var cancellationToken = new CancellationToken();

var authToken = await publicClientApplication
    .AcquireTokenInteractive(scopes)
    .ExecuteAsync(cancellationToken);
            
await publicClientApplication
    .AcquireTokenSilent(scopes, authToken.Account)
    .ExecuteAsync(cancellationToken);

    SaslMechanism oauth2;
    if (client.AuthenticationMechanisms.Contains("OAUTHBEARER"))
    {
        oauth2 = new SaslMechanismOAuthBearer(authToken.Account.Username, authToken.AccessToken);
    } 
    else
    {
        oauth2 = new SaslMechanismOAuth2(authToken.Account.Username, authToken.AccessToken);
    }

    await client.AuthenticateAsync(oauth2);
    await client.DisconnectAsync (true);

这一行触发浏览器 window 打开 https://login.microsoftonline.com/:

var authToken = await publicClientApplication
    .AcquireTokenInteractive(scopes)
    .ExecuteAsync(cancellationToken);

此控制台应用程序将运行无人值守。如何在不打开 Web 浏览器的情况下获取令牌并进行身份验证?

这是对您最新评论的答复,因为这是我的最终推荐。因此,首先,您应该决定是代表用户访问数据,还是作为管理员授予权限的应用程序访问数据。

第一步是register your app

第二步是获取访问令牌。这将根据您选择的方法而有所不同。每个教程:acting on behalf of the user or acting without the user, but granted permission from admin.

获得访问令牌后,您可以调用 Microsoft Graph API。重要的是,您始终必须调用 Microsoft Graph API。没有其他官方方式(据我所知)可以与 Microsoft 的服务进行通信。您可以使用 Microsoft Graph Explorer, however it's VERY limited with it's defaul urls/parameters, so I suggest taking a look at the docs.

尝试请求

根据您的描述,您首先要获取UserID。执行此操作的方式将根据您选择的身份验证类型而有所不同。

  • 如果您选择代表用户行事,您应该能够使用此端点获取该 (ID):https://graph.microsoft.com/v1.0/me/
  • 如果您选择在管理员同意的情况下充当应用程序,您应该能够使用带有搜索查询参数的 https://graph.microsoft.com/v1.0/me/people/?$search= 来搜索用户。 Here are the docs for this endpoint

现在,唯一剩下的就是将该 ID 提供给 Outlook api 方法之一。您可以找到它们的文档 here. Specifically, it seems like you want to list all messages and then read a specific message.

此外,请注意您对哪种身份验证使用了哪些方法。代表用户,您通常需要包含 /me 的 url,代表具有给定管理员权限的应用程序,您通常需要一些能够让您传递用户 ID 的端点。

希望我有所帮助!

PS:此响应中没有代码,因为如果没有您在 Azure 上的决定、操作等,有很多东西无法编码。我建议您使用我之前链接的 Microsoft 文档阅读一些关于 auth 和 graph api 的内容。