Я разрабатываю консольное приложение для личного использования, которое использует управляемый API веб-служб Exchange в качестве альтернативы Redemption (который я, к сожалению, не могу использовать). Моя конечная цель - использовать приложение в запланированной задаче 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 и, похоже, передает мои учетные данные Windows в Exchange, когда я использую клиент Outlook, без необходимости явно вводить мои учетные данные для клиента Outlook. Есть ли что-то подобное в управляемом API EWS, которое позволит моему приложению входить в систему с моими учетными данными Windows без их явной передачи? Я знаю, что вы можете зарегистрировать свое приложение и использовать OAuth, но я хотел избежать этого, поскольку это для моего личного использования, и я не уверен, что смогу зарегистрировать свое приложение на работе.
Если это невозможно, я видел несколько статей, например этот, в котором упоминается использование диспетчера учетных данных Windows, и это выглядит многообещающе, но похоже, что мне все еще может потребоваться что-то дополнительное с моим паролем до хранение его. Если я создам учетные данные в диспетчере учетных данных Windows и реализую код по ссылке выше, используя приведенный ниже код (и используя Пакет NuGet CredentialManagement), пароль отображается в виде обычного текста.
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
в управляемом API EWS. К сожалению, я не видел примеров его использования. Это альтернативный метод аутентификации? Можно ли использовать самозаверяющий сертификат для этого метода? Если да, требуется ли хранить закрытый ключ на сервере Exchange Online?
Я открыт для других идей и ценю помощь.
Спасибо!