1

我正在开发一个供个人使用的控制台应用程序,它使用 Exchange Web 服务托管 API 作为 Redemption 的替代方案(很遗憾,我不能使用它)。我的最终目标是在 Windows 计划任务中使用该应用程序连接到我的 Exchange 邮箱并执行一些任务,例如在一年中的特定时间创建文件夹、将电子邮件移动到这些文件夹、设置项目的保留策略等。

该应用程序运行良好,但我很好奇如何最好地为该应用程序实施安全身份验证,以便我可以在工作中使用它。我知道Exchange Online 不会让我使用默认凭据自动连接(不确定这是否包括现代身份验证...见下文),我必须明确传递它们。在开发过程中,我使用以下代码将我的用户 ID 和密码显式传递给 Exchange:

string userId = UserPrincipal.Current.EmailAddress;
SecureString securePwd = new SecureString();

Console.Write("Current User ID/Email Address: {0}\n", userId);
Console.Write("Enter Password: ");

do
{
    key = Console.ReadKey(true);

    // Ignore the Backspace and Enter keys.
    if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter)
    {
        // Append the character to the password.
        securePwd.AppendChar(key.KeyChar);
        Console.Write("*");
    }
    else
    {
        if (key.Key == ConsoleKey.Backspace & securePwd.Length > 0)
        {
            securePwd.RemoveAt(securePwd.Length - 1);
            Console.Write("\b \b");
        }
        else if (key.Key == ConsoleKey.Enter)
        {
            break;
        }
    }
} while (true);

service.Credentials = new WebCredentials(new NetworkCredential(userId, securePwd));

我希望,因为我将使用Run whether user is logged on or not选定的选项创建我的 Windows 计划任务并输入我的密码,所以该应用程序可以使用并传递计划任务使用的相同凭据,因此我不必将密码存储在全部,但我还没有找到任何允许这样做的东西。

我的工作已启用 Exchange Online 的现代身份验证,当我使用 Outlook 客户端时,这似乎将我的 Windows 凭据传递给 Exchange,而无需我显式输入 Outlook 客户端的凭据。EWS Managed API 中是否有类似的东西允许我的应用使用我的 Windows 凭据登录而无需显式传递它们?我知道您可以注册您的应用程序并使用 OAuth,但我想避免这种情况,因为这是供我个人使用的,我不确定我能否在工作中注册我的应用程序。

如果上述方法不可行,我看过很多文章,比如这篇文章,其中提到了使用 Windows 凭据管理器,看起来很有希望,但看起来我可能仍然需要在之前使用我的密码做一些额外的事情存储它。如果我在 Windows 凭据管理器中创建凭据并使用下面的代码(并使用CredentialManagement NuGet 包)在上面的链接中实现代码,则密码将以纯文本形式显示。

private const string PasswordName = "CredentialTest";

public static void Main(string[] args)
{
    LoadCredential();
    Console.ReadKey();
}

public static void LoadCredential()
{
    using (var cred = new CredentialManagement.Credential())
    {
        cred.Target = PasswordName;
        cred.Load();

        Console.WriteLine("Password: {0}", cred.Password);            
    }
}

是否建议将密码作为安全字符串读取,使用存储在 app.config 文件的加密部分中的密钥对其进行加密,并将加密的密码存储在 Windows 凭据管理器中?

我遇到的另一个有趣的项目是ClientCertificateCredentialsEWS 托管 API 中的类。不幸的是,我还没有看到任何使用它的例子。这是另一种身份验证方法吗?这种方法可以使用自签名证书吗?如果是这样,是否需要在 Exchange Online 服务器上存储私钥?

我对其他想法持开放态度并感谢您的帮助。

谢谢!

4

1 回答 1

1

Windows 凭据管理器当然是一个选项(这就是 Outlook 仍然存储 POP3/IMAP4/SMTP 密码并用于存储 Exchange 凭据的方式)。
请记住,Office 365 将在 2020 年 10 月关闭基本身份验证
。OAuth 可能是一个选项,但这意味着您仍然需要以某种方式提示用户输入凭据并以某种方式存储访问和刷新令牌。
首选的解决方案是使用基于证书的身份验证 - 参见例如https://developermessaging.azurewebsites.net/2018/09/11/authenticating-against-exchange-web-services-using-certificate-based-oauth2-tokens/
但是这需要在服务器端导入证书,这需要管理员权限。

于 2019-10-27T18:19:14.067 回答