2
votes

Vérifier si le compte d'utilisateur existe dans Azure Active Directory

Je dois envoyer un e-mail aux utilisateurs à partir d'une application ASP.NET Core 2, en suivant certaines règles métier. Cependant, je dois m'assurer que le compte auquel l'e-mail est envoyé existe réellement (pour une raison quelconque, il se peut que le compte ait cessé d'être valide). Le client utilise Azure Active Directory, je dois donc interroger AAD d'une manière ou d'une autre pour qu'il me permette de savoir si le compte existe ou non.

Jusqu'à présent, j'ai recherché Microsoft Graph comme moyen de le faire, mais chaque exemple que j'ai vu jusqu'à présent nécessite une authentification préalable et utilise un mécanisme d'authentification déléguée. Je ne veux pas que mes utilisateurs aient à s'authentifier ni à afficher l'écran d'authentification.

Dans cette situation, que recommanderiez-vous d'utiliser? Si vous pouvez également me donner un exemple, ce serait formidable. Merci!


0 commentaires

3 Réponses :


1
votes

Finalement, j'ai trouvé quelque chose de réalisable. Ce n'est pas sympa et il utilise un logiciel de prévisualisation. Tout d'abord, installez les packages Microsoft.Graph et Microsoft.Identity.Client. Ensuite, installez Microsoft.Graph.Auth, qui au moment de la rédaction de cet article, est en préversion (v1.0.0-preview.1), vous devrez donc cocher la case "Inclure la pré-version" dans le gestionnaire de nuget.

Ensuite, dans votre AAD, vous devez obtenir le ClientId, TenantId et SecretId. Dans mon cas, mon application utilisait déjà l'authentification AAD, donc j'avais déjà ClientId et TenantId dans mon fichier appsettings.json. Je n'avais besoin que de créer un nouveau SecretId (dans la section Certificat et secrets de l'enregistrement de mon application). Ensuite, j'ai dû ajouter des autorisations (dans la section des autorisations API de l'enregistrement de mon application) pour inclure Microsoft.Graph avec au moins l'autorisation 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;
}

Ici, la fonction prend une chaîne séparée par des points-virgules pour chaque compte. La méthode GetAsync lèvera une ServiceException si l'utilisateur n'existe pas. Je n'aime pas ça, mais je n'ai pas trouvé d'autre moyen. Alors c'est à peu près tout. J'espère que cela aide quelqu'un d'autre et j'espère que quelqu'un pourra éventuellement trouver une meilleure solution.


0 commentaires

2
votes

Vous n'avez pas vraiment besoin de lancer / attraper une exception pour chaque utilisateur invalide comme vous le faites dans le code actuel. Je n'ai rien contre la gestion des exceptions en général pour d'autres raisons, mais pour voir si l'utilisateur existe ou non, vous pouvez essayer d'utiliser Filter .

Ainsi, votre requête graphique pourrait ressembler à -

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;
}

J'ai montré startswith ici parce que l' eq n'a pas fonctionné pour moi dans un essai rapide. Bien que je recommande deux choses:

Voici une version modifiée de votre code.

Notez que je vérifie que le nombre de collections est> 0 et que je ne vérifie pas qu'il est nul, car même au cas où l'utilisateur ne serait pas trouvé, UsersCollectionPage n'était pas nul pour mon test.

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

Par ailleurs, je ne suis pas sûr de vos besoins, mais vous pourriez probablement faire preuve de créativité en combinant plusieurs noms d'utilisateur dans une seule requête, puis en vérifiant le nombre de résultats ou d'autres propriétés. Vous pouvez utiliser or entre plusieurs critères ou probablement utiliser any opérateur. Cependant, je n'ai pas vraiment essayé cela.


0 commentaires

1
votes

Importez les espaces de noms suivants (vous devez installer les packages appropriés à l'aide de nuget):

var user = await graphServiceClient.Users.Request().Filter("mail eq '" + UserEmailAddress + "'").GetAsync();
if (user.Count == 0) {
    //user not exist
}

Définissez les valeurs de votre application Azure AD:

public static GraphServiceClient CreateGraphServiceClient()
{
  var clientCredential = new ClientCredential(_appId, _appSecret);
  var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/{_tenant}");
  var authenticationResult = authenticationContext.AcquireTokenAsync("https://graph.microsoft.com", clientCredential).Result;

  var delegateAuthProvider = new DelegateAuthenticationProvider((requestMessage) =>
  {
    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authenticationResult.AccessToken);

    return Task.FromResult(0);
   });

  return new GraphServiceClient(delegateAuthProvider);
 }


var graphServiceClient = GraphServiceClientHelper.CreateGraphServiceClient();

Créez un client de service graphique en utilisant ceci:

private string _tenant => "your_tenant_id";
private string _appId => "your_ad_app_client_id";
private string _appSecret => "your_app_client_secret";

Ensuite, appelez l'API graphique et filtrez les utilisateurs par adresse e-mail comme suit:

using Microsoft.Graph;
using Microsoft.IdentityModel.Clients.ActiveDirectory;


0 commentaires