AcquireTokenSilent всегда не удалось автоматически получить токен

Используя ADAL, у меня есть два AuthenticationContext с использованием Token Cache, сохраненного в SQL.

Используя AcquireTokenByAuthorizationCode, он записывает токен в базу данных, но при использовании AcquireTokenSilent я всегда получаю

Не удалось получить токен автоматически. Метод вызова AcquireToken

Вот подробности для репликации проблемы:

Я создаю контекст

AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));

Затем я получаю токен авторизацией

authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential);

На этом этапе он сохраняет запись в базе данных

Затем, если я позвоню, я получу исключение.

authContext.AcquireTokenSilent(_authority, _clientCredential, new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)).AccessToken;

Я также пробовал с тем же результатом:

authContext.AcquireTokenSilent(_authority, _clientId).AccessToken;
authContext.AcquireTokenSilent(_authority, _clientCredential, UserIdentifier.AnyUser).AccessToken;

Я публикую свою реализацию AzureAdalCache в этой сути.

Каждая запись кэша подобна этой.

Что мне не хватает?

Обновить

На основе ответа на комментарии @vibronet у меня есть это

AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));
authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential, _eWSResource);
string result = authContext.AcquireTokenSilent(_eWSResource, _clientId, UserIdentifier.AnyUser).AccessToken;

person Ricardo Polo Jaramillo    schedule 20.04.2015    source источник


Ответы (5)


Проблема заключалась в том, что в основном я использовал Common Authority https://login.windows.net/common/oauth2/authorize в своем приложении. Это работает для AcquireTokenByAuthorizationCode(), но не для AcquireTokenSilent().

Поэтому мне нужно было сохранить TenantId при вызове AcquireTokenByAuthorizationCode(), а орган использует полномочия, такие как https://login.windows.net/<tenant ID>/oauth2/authorizewhen call AcquireTokenSilent(). Таким образом, работает тот же код, что и выше.

person Ricardo Polo Jaramillo    schedule 21.04.2015
comment
Также обратите внимание, что в некоторых версиях ADAL идентификатор GUID, являющийся идентификатором TenantId, и уникальный идентификатор пользователя чувствительны к регистру: они должны быть строчными, чтобы кэш мог правильно загрузить их. - person Andacious; 08.07.2016
comment
любой пример кода поможет. потому что AcquireTokenByAuthorizationCodeAsync будет иметь другие параметры. - person Kurkula; 07.03.2017
comment
Для меня было достаточно просто вставить URL-адрес органа, как этот: https://login.windows.net/<tenant ID>/ - person Rodion Sychev; 18.07.2018

Я не понимаю вызова:

authContext.AcquireTokenSilent(
    _authority,
    _clientCredential,
    new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)
).AccessToken;

UserIdentifier должен совпадать со значением в кеше, а CompanyID не похож ни на один из идентификаторов, которые вы возвращаете для токена.

Пожалуйста, взгляните на образец, на который я указал вам в другом потоке, и, в частности, на идентификатор, используемый при вызове AcquireTokenSilent в https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet/blob/master/TodoListWebApp/Controllers/TodoListController.cs

Вы не можете выбрать, какой идентификатор использовать в этом вызове, это определяется тем, какие утверждения выдает AAD. Единственные идентификаторы, которые вы можете выбрать, находятся на уровне экземпляра кэша, а не в отдельных вызовах AcquireToken*.

person vibronet    schedule 20.04.2015
comment
Спасибо @vibronet. Я вижу, что мне было очень плохо. Я должен использовать строку userObjectID = ClaimsPrincipal.Current.FindFirst(schemas.microsoft.com/identity /претензии/; Но... как мне получить доступ к ClaimsPrincipal.Current в фоновом задании? Я получаю ссылку на объект, не установленную на экземпляр объекта - person Ricardo Polo Jaramillo; 20.04.2015
comment
Вы должны где-то сохранить правильное значение и передать его :) или вам нужно открыть веб-API, если вы хотите запускать логику по запросу. - person vibronet; 20.04.2015
comment
Но... как я могу получить заявку на веб-сайте, если на моем веб-сайте нет проверки подлинности Azure? Я имею в виду, что пользователи на веб-сайте являются локальными для приложения (с использованием ASP.NET Identity EntityFramework). Я разрешаю пользователю зарегистрировать свою лазурную рекламу для какой-то фоновой работы, но я не буду менять аутентификацию и утверждения на веб-сайте. Итак, есть идеи о том, что я должен передать как UserId для AcquireTokenSilent()? - person Ricardo Polo Jaramillo; 20.04.2015
comment
Вы тот, кто решает, что такое контекст. Если у вас есть сеанс пользователя с локальной учетной записью, вы можете создать экземпляр кэша ADAL только для этой локальной учетной записи. В этот момент вам даже не нужно указывать идентификатор пользователя при вызове acquiretokensilent, учитывая отсутствие двусмысленности. Именно так реализован кеш в нашем образце - person vibronet; 20.04.2015
comment
Как я уже сказал в посте, я уже пробовал это с тем же результатом. Я вызываю authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential, _eWSResource); А затем authContext.AcquireTokenSilent(_eWSResource, _clientId); Он не говорит, что я должен вызвать AcquireToken(). Я не передаю идентификатор пользователя, но TokenCache получает идентификатор пользователя в качестве параметра. - person Ricardo Polo Jaramillo; 20.04.2015
comment
В посте вы передавали авторитет вместо ресурса. Кроме того, вы должны передать useridentifier.anyuser. Еще одна вещь, которую вы, возможно, захотите сделать, это включить ведение журнала, чтобы точно увидеть, где что-то развалилось. - person vibronet; 20.04.2015
comment
Я только что обновил вопрос текущим кодом. С этим кодом у меня такое же поведение. Любая идея о том, что это может быть или как я могу включить ведение журнала, чтобы попытаться найти, что не так? - person Ricardo Polo Jaramillo; 20.04.2015
comment
См. раздел журналов в файле read me на github.com/AzureAD/azure-activedirectory. -библиотека-для-дотнета - person vibronet; 20.04.2015
comment
Я действительно не могу понять эту вещь :( Используя регистратор, я вижу, что он сериализуется и использует токен с GUID. Я никогда не передаю d529b8e4-44cd-4fc5-93e2-637dd20341a9, и когда я консультируюсь с UserIdentifier.AnyUser, он запрашивает токен с Guid 6a360032-c1f1-4054-b8da-304cbbab4a78 Я не понимаю, почему с помощью AnyUser запрашивается этот идентификатор. - person Ricardo Polo Jaramillo; 20.04.2015
comment
Я отправил вам сообщение. Также создано упрощенное репо, воспроизводящее проблему. github.com/ricardopolo/AdalIssue - person Ricardo Polo Jaramillo; 20.04.2015

Проверьте, существует ли токен в кеше, иначе выйдите из системы и попросите пользователя войти в систему.

AuthenticationContext authContext = new AuthenticationContext(Startup.Authority,
                        new NaiveSessionCache(userObjectID));
                    if (authContext.TokenCache.Count == 0)
                    {
                        authContext.TokenCache.Clear();
                        CosmosInterface.Utils.AuthenticationHelper.token = null;
                        HttpContext.GetOwinContext().Authentication.SignOut(
                            OpenIdConnectAuthenticationDefaults.AuthenticationType,
                            CookieAuthenticationDefaults.AuthenticationType);
                    }
person Kurkula    schedule 08.03.2017

У меня была такая же проблема в ASPNetCore (1.0), и причина заключалась в том, что я не сохранял токен аутентификации после входа в систему. Я решил ее, добавив OnAuthorizationCodeReceived в класс Startup и изменив тип ответа на ResponseType = OpenIdConnectResponseType.CodeIdToken.

Надеюсь, поможет.

Пример: https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore/blob/aspnet10/WebApp-WebAPI-OpenIdConnect-DotNet/Startup.cs#L100

person teocomi    schedule 13.10.2016
comment
Ссылка мертва - person Kevin R.; 27.03.2018
comment
Исправил @KevinR. - person teocomi; 27.03.2018

Это старый вопрос, но мне нужно было очистить файлы cookie на клиенте, а затем он заставил браузер выполнить повторную аутентификацию, и все снова стало хорошо.

person ScottFoster1000    schedule 06.11.2018