Проверьте, существует ли учетная запись пользователя в Azure Active Directory - PullRequest
1 голос
/ 14 октября 2019

Мне нужно отправить электронное письмо пользователям из приложения ASP.NET Core 2, следуя некоторым бизнес-правилам. Однако мне нужно убедиться, что учетная запись, на которую отправляется электронная почта, действительно существует (по какой-то причине, возможно, учетная запись перестала быть действительной). Клиент использует Azure Active Directory, поэтому мне нужно как-то запросить AAD, чтобы он знал, существует ли учетная запись или нет.

До сих пор я искал Microsoft Graph как способ сделать это, однако каждый приведенный мной пример требует предварительной аутентификации и использования механизма аутентификации делегата. Я не хочу, чтобы мои пользователи проходили аутентификацию или запрашивали экран аутентификации.

Что бы вы порекомендовали использовать в данной ситуации? Если вы также можете указать мне пример, это было бы здорово. Спасибо!

Ответы [ 2 ]

1 голос
/ 15 октября 2019

Вам не нужно создавать исключение / перехват для каждого недопустимого пользователя, как вы делаете в текущем коде. Я не имею ничего против обработки исключений в целом по другим причинам, но чтобы увидеть, существует ли пользователь или нет, вы можете попробовать использовать Filter.

Таким образом, ваш запрос графа может выглядеть как -

https://graph.microsoft.com/v1.0/users?$filter=startswith(userPrincipalName,'someuser@mytenant.onmicrosoft.com')

Я показал startswith здесь, потому что eq не помогло мне в быстром испытании. Хотя я бы порекомендовал две вещи:

Вот модифицированная версия для вашего кода.

Обратите внимание, что я проверяю, чтобы количество собраний было> 0, и не проверяю, чтобы оно было нулевым, поскольку даже в случае, если пользователь не найден, UsersCollectionPage не был нулевым для моего тестового прогона.

using Microsoft.Identity.Client;
using Microsoft.Graph.Auth;
using Microsoft.Graph;
...

private async Task<bool> ValidateAccounts(string accounts) {
    var confidentialClientApplication = ConfidentialClientApplicationBuilder
        .Create("clientId here")
        .WithTenantId("tokenId here")
        .WithClientSecret("secret here")
        .Build();
    var authProvider = new ClientCredentialProvider(confidentialClientApplication);
    var graphClient = new GraphServiceClient(authProvider);

    var valid = true;
    try {
        foreach (var account in accounts.Split(';')) {
            var user = await graphClient.Users.Request().Filter("startswith(userPrincipalName, '" + account + "')").GetAsync();

            if (user.Count <= 0) {
                valid = false;
                break;
            }
        }
    } catch (ServiceException ex) {
        valid = false;
    }

    return valid;
}

Кстати, я не уверен в ваших требованиях, но вы могли бы проявить творческий подход, объединив несколько имен пользователей в одном запросе, а затем проверив счетчик результатов или другие свойства. Вы можете использовать or между несколькими критериями или, возможно, использовать оператор any. Я действительно не пробовал это все же.

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

Наконец-то я придумал что-то выполнимое. Это не хорошо, и он использует предварительный просмотр программного обеспечения. Сначала установите пакеты Microsoft.Graph и Microsoft.Identity.Client. Затем установите Microsoft.Graph.Auth, который на момент написания этой статьи находился в режиме предварительного просмотра (v1.0.0-preview.1), поэтому вам нужно будет поставить галочку «включить предварительный выпуск» в диспетчере nuget.

Затем в вашем AAD вам необходимо получить ClientId, TenantId и SecretId. В моем случае мое приложение уже использовало аутентификацию AAD, поэтому у меня уже были ClientId и TenantId в моем файле appsettings.json. Мне нужно было только создать новый SecretId (в разделе «Сертификаты и секреты» при регистрации моего приложения). Затем мне нужно было добавить разрешения (в разделе разрешений API моей регистрации приложения), чтобы включить Microsoft.Graph как минимум с разрешением User.Read.All.

using Microsoft.Identity.Client;
using Microsoft.Graph.Auth;
using Microsoft.Graph;
...

private async Task<bool> ValidateAccounts(string accounts) {
    var confidentialClientApplication = ConfidentialClientApplicationBuilder
        .Create("clientId here")
        .WithTenantId("tokenId here")
        .WithClientSecret("secret here")
        .Build();
    var authProvider = new ClientCredentialProvider(confidentialClientApplication);
    var graphClient = new GraphServiceClient(authProvider);

    var valid = true;
    try {
        foreach (var account in accounts.Split(';')) {
            var user = await graphClient.Users[account]
                .Request()
                .GetAsync();
            if (user == null) {
                valid = false;
                break;
            }
        }
    } catch (ServiceException ex) {
        valid = false;
    }

    return valid;
}

Здесь функция принимает строку, разделенную точкой с запятой, для каждой учетной записи. Метод GetAsync вызовет исключение ServiceException, если пользователь не существует. Мне это не нравится, но я не мог найти другой путь. Так вот и все. Надеюсь, что это поможет кому-то еще, и надеюсь, что кто-то может в конечном итоге найти лучшее решение.

...