4
votes

Obtenez un jeton d'accès dans un site Web intégré à Azure AD B2C

J'ai une application ASP.NET MVC Core 2.2, qui s'intègre à un Azure AD B2C pour authentifier les utilisateurs. Je peux me connecter correctement et l'utilisateur est authentifié.

J'ai également créé une API Web ASP.NET Core qui est également intégrée à Azure B2C AD, et le but est d'appeler cette API Web à partir d'un ASP.NET Méthode d'action du contrôleur MVC.

J'ai donc ajouté le code de test suivant dans le contrôleur du site MVC:

if (HttpContext.User.Identity.IsAuthenticated)
{
    string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
    TokenCache userTokenCache = new MSALSessionCache(signedInUserID, HttpContext).GetMsalCacheInstance();
    ConfidentialClientApplication cca = new ConfidentialClientApplication(mgpPortalApplicationId, authority, redirectUri, new ClientCredential(mgpPortalSecretKey), userTokenCache, null);                
    IEnumerable<IAccount> accounts = await cca.GetAccountsAsync();
    IAccount firstAccount = accounts.FirstOrDefault();
    AuthenticationResult result = await cca.AcquireTokenSilentAsync(null, firstAccount, authority, false);
    HttpClient client = new HttpClient();
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:44307/api/values");
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
    HttpResponseMessage response = await client.SendAsync(request);
}

Le problème est que comptes .FirstOrDefault () renvoie null. Je ne sais pas pourquoi:

Quelqu'un a-t-il une idée de ce que je fais mal? Merci pour tous les conseils!

Observation supplémentaire: si je lance la démo https://github.com/Azure-Samples/active-directory-b2c-dotnetcore-webapp , qui utilise un Microsoft.Identity.Client plus ancien, puis l'appel à cca.Users.FirstOrDefault () rend correctement un utilisateur. Cependant, lorsque je mets à niveau ce projet de démonstration vers Microsoft.Identity.Client 2.7 (qui est nécessaire pour .NET Core 2.2), je dois passer un IAccount et je dois donc appeler GetAccountsAsync () , et cela renvoie aucun compte.


0 commentaires

3 Réponses :


1
votes

Premièrement, vous devez demander les étendues dont vous avez besoin pour accéder à votre api lorsque vous invoquez AcquireTokenSilentAsync

// Retrieve the token with the specified scopes
var scope = AzureAdB2COptions.ApiScopes.Split(' ');
string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
TokenCache userTokenCache = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();
ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);

AuthenticationResult result = await cca.AcquireTokenSilentAsync(scope, cca.Users.FirstOrDefault(), AzureAdB2COptions.Authority, false);

Et vous devez implémenter l'acquisition initiale de jetons et enregistrer les jetons dans le cache de jetons MSAL en utilisant AuthorizationCodeReceived notification du middleware d'autorisation:

public async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
    // Use MSAL to swap the code for an access token
    // Extract the code from the response notification
    var code = context.ProtocolMessage.Code;

    string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;
    TokenCache userTokenCache = new MSALSessionCache(signedInUserID, context.HttpContext).GetMsalCacheInstance();
    ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
    try
    {
        AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, AzureAdB2COptions.ApiScopes.Split(' '));


        context.HandleCodeRedemption(result.AccessToken, result.IdToken);
    }
    catch (Exception ex)
    {
        //TODO: Handle
        throw;
    }
}

Pour que lors de l'acquisition d'un jeton dans le contrôleur, MSAL recherche le cache et renvoie tout jeton mis en cache qui correspond à l'exigence. Si ces jetons d'accès sont expirés ou qu'aucun jeton d'accès approprié n'est présent, mais qu'un jeton d'actualisation est associé, MSAL l'utilisera automatiquement pour obtenir un nouveau jeton d'accès et le renvoyer de manière transparente:

AuthenticationResult result = await cca.AcquireTokenSilentAsync(scope, cca.Users.FirstOrDefault(), AzureAdB2COptions.Authority, false);

Voici l'exemple de code utilisant ASP.NET Core 2.0 et MSAL 2, veuillez lire le README.md pour une explication détaillée.

Vous pouvez également cliquer sur ici pour un exemple de code qui authentifie l'utilisateur auprès d'Azure AD B2C et acquiert un jeton d'accès à l'aide de MSAL.NET à l'aide d'ASP.NET Core 2.1.

p>


2 commentaires

Merci! Mais d'abord, il semble, comme j'utilise ASP.NET Core 2.2, ce OnAuthorizationCodeReceived est déjà appelé par défaut? Parce que dans startup.cs, je vois que AddAzureADB2C est appelé, ce qui fait cela, si j'ai raison. Deuxièmement, je dois obtenir IAccount, pas IUser, car il s'agit d'ASP.NET Core 2.2 ... mais je reçois null de GetAccountsAsync, ce qui provoque également l'échec de AcquireTokenSilentAsync ...


Je viens d'ajouter une observation supplémentaire à la question.



0
votes

@ L-Four, il y a en fait une branche du code que vous mentionnez qui est déjà mise à jour vers la dernière version de MSAL: active-directory-b2c-dotnetcore- application web

En disant cela, lorsque je l'exécute, j'obtiens une erreur non autorisée. Donc pas vraiment sûr de ce qui se passe avec ça. Mais je récupère un compte.


0 commentaires

1
votes

L ' .NETCore B2C Web app a été mise à jour pour utiliser MSAL v2.7. L'étendue utilisée était incorrecte, donc l'exemple utilise maintenant l'étendue correcte et un jeton d'accès est renvoyé.

"ApiScopes": "https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read"


0 commentaires