Получить токен доступа на веб-сайте, интегрированном с Azure AD B2C - PullRequest
0 голосов
/ 23 января 2019

У меня есть приложение ASP.NET MVC Core 2.2, которое интегрируется с Azure AD B2C для аутентификации пользователей. Я могу войти в систему правильно, и пользователь аутентифицирован.

Я также создал базовый веб-API ASP.NET, который также интегрирован с Azure B2C AD, и целью является вызов этого веб-API из метода действия контроллера ASP.NET MVC.

Итак, я добавил следующий тестовый код в контроллер сайта 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);
}

Проблема в том, что accounts.FirstOrDefault() возвращает ноль. Не уверен почему:

Кто-нибудь имеет представление о том, что я делаю неправильно? Спасибо за любые подсказки!

Дополнительное наблюдение: если я запустил демонстрационную версию https://github.com/Azure-Samples/active-directory-b2c-dotnetcore-webapp,, которая использует более старый Microsoft.Identity.Client, то вызов cca.Users.FirstOrDefault () вернет пользователя правильно. Однако, когда я обновляю этот демонстрационный проект до Microsoft.Identity.Client 2.7 (который необходим для .NET Core 2.2), я должен передать IAccount и поэтому мне нужно вызвать GetAccountsAsync(), и это вернет no аккаунт.

Ответы [ 3 ]

0 голосов
/ 05 февраля 2019

@ L-Four, на самом деле есть ветвь упомянутого вами кода, которая уже обновлена ​​до последней версии MSAL: active-directory-b2c-dotnetcore-webapp

Sayingчто при запуске я получаю несанкционированную ошибку.Так что не совсем уверен, что с этим.Но я вернул счет.

0 голосов
/ 05 февраля 2019

Веб-приложение .NETCore B2C обновлено для использования MSAL v2.7.Используемая область была неправильной, поэтому в примере теперь используется правильная область, и возвращается токен доступа.

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

0 голосов
/ 24 января 2019

Во-первых, вам нужно запросить области, необходимые для доступа к вашему API, при вызове AcquireTokenSilentAsync

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

И вам необходимо реализовать первоначальное получение токенов и сохранить токены в кэше токенов MSAL, используя AuthorizationCodeReceived уведомление о промежуточном программном обеспечении авторизации:

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

Чтобы при получении токена в контроллере MSAL проверял кеш и возвращал любой кэшированный токен, который соответствует требованию. Если срок действия таких токенов доступа истек или отсутствуют подходящие токены доступа, но есть связанный токен обновления, MSAL автоматически использует его для получения нового токена доступа и его прозрачного возврата:

// 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);

Здесь - пример кода с использованием ASP.NET Core 2.0 и MSAL 2, пожалуйста, прочитайте README.md для подробного объяснения.

Также можно щелкнуть здесь для примера кода, который аутентифицирует пользователя в Azure AD B2C и получает токен доступа с помощью MSAL.NET с использованием ASP.NET Core 2.1.

...