Как проверить подлинность консольного приложения с помощью Exchange Online / EWS Managed API? - PullRequest
0 голосов
/ 25 октября 2019

Я разрабатываю консольное приложение для личного использования, которое использует управляемый API-интерфейс веб-служб Exchange в качестве альтернативы погашению (которое, к сожалению, я не могу использовать). Моя конечная цель - использовать приложение в запланированной задаче Windows для подключения к моему почтовому ящику Exchange и выполнять некоторые задачи, такие как создание папок в определенное время в течение года, перемещение писем в эти папки, настройка политик хранения для элементов и т. Д.

Приложение работает хорошо, но мне интересно, как лучше реализовать безопасную аутентификацию для приложения, чтобы я мог использовать это на работе. Я знаю, Exchange Online не разрешит мне автоматически подключаться с учетными данными по умолчанию (не уверен, включает ли это Современная аутентификация ... см. Ниже), и мне придется явно их передавать. В процессе разработки я явно передаю свой идентификатор пользователя и пароль в 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));

Я надеялся, так как я буду создавать запланированное задание Windows с выбранным параметром Run whether user is logged on or notи введет мой пароль, чтобы приложение могло использовать и передавать те же учетные данные, которые использует запланированная задача, поэтому мне вообще не нужно хранить пароль, но я пока не нашел ничего, что позволило бы это.

В моей работе включена современная аутентификация с Exchange Online, и при использовании клиента Outlook мои учетные данные Windows передаются, как представляется, без необходимости явного ввода учетных данных для клиента 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?

Еще одним интересным элементом, с которым я столкнулся, был класс ClientCertificateCredentials в EWS Managed API. К сожалению, я не видел ни одного примера его использования. Это альтернативный метод аутентификации? Можно ли использовать самозаверяющий сертификат для этого метода? Если да, то нужно ли хранить закрытый ключ на сервере Exchange Online?

Я открыт для других идей и благодарен за помощь.

Спасибо!

1 Ответ

0 голосов
/ 27 октября 2019

Диспетчер учетных данных Windows, конечно, является опцией (именно так Outlook по-прежнему хранит пароли POP3 / AAMP4 / SMTP и используется для хранения учетных данных Exchange).
Имейте в виду, что Office 365 отключит обычную проверку подлинности в октябре 2020 года.
OAuth может быть вариантом, но это означает, что вам все равно нужно как-то запрашивать у пользователя учетные данные и сохранять маркеры доступа и обновлениякаким-то образом.
Предпочтительным решением является использование аутентификации на основе сертификатов - см., например, https://developermessaging.azurewebsites.net/2018/09/11/authenticating-against-exchange-web-services-using-certificate-based-oauth2-tokens/
Но для этого требуется импортировать сертификат на стороне сервера, что требует прав администратора.

...