У меня есть приложение, в котором пользователь выполняет аутентификацию в Office365 с помощью библиотеки AzureAD для Android. .
Работает хорошо, пользователи могут аутентифицироваться и работать с приложением. К сожалению, через некоторое время они начинают нажимать AuthenticationException
с кодом ADALError.AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED
в качестве кода ошибки.
Я проверил исходный код AzurelAD. Единственное место, где решается эта проблема, - это acquireTokenAfterValidation()
метод:
private AuthenticationResult acquireTokenAfterValidation(CallbackHandler callbackHandle,
final IWindowComponent activity, final boolean useDialog,
final AuthenticationRequest request) {
Logger.v(TAG, "Token request started");
// BROKER flow intercepts here
// cache and refresh call happens through the authenticator service
if (mBrokerProxy.canSwitchToBroker()
&& mBrokerProxy.verifyUser(request.getLoginHint(),
request.getUserId())) {
.......
Logger.v(TAG, "Token is not returned from backgroud call");
if (!request.isSilent() && callbackHandle.callback != null && activity != null) {
....
} else {
// User does not want to launch activity
String msg = "Prompt is not allowed and failed to get token:";
Logger.e(TAG, msg, "", ADALError.AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED);
callbackHandle.onError(new AuthenticationException(
ADALError.AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED, msg));
}
// It will start activity if callback is provided. Return null here.
return null;
} else {
return localFlow(callbackHandle, activity, useDialog, request);
}
}
Мой исходный код:
authenticator.getAccessTokenSilentSync(getMailService());
public class Authenticator {
..............
public String getAccessTokenSilentSync(ServiceInfo serviceInfo) {
throwIfNotInitialized();
return getAuthenticationResultSilentSync(serviceInfo).getAccessToken();
}
private AuthenticationResult getAuthenticationResultSilentSync(ServiceInfo serviceInfo) {
try {
return authenticationContext.acquireTokenSilentSync(
serviceInfo.ServiceResourceId,
Client.ID,
userIdentity.getAdUserId());
} catch (AuthenticationException ex) {
// HERE THE EXCEPTION IS HANDLED.
}
}
..............
}
Stacktrace я получаю:
<package name>.data_access.error_handler.AuthenticationExceptionWithServiceInfo: Refresh token is failed and prompt is not allowed at com.microsoft.aad.adal.AuthenticationContext.localFlow(AuthenticationContext.java:1294) at com.microsoft.aad.adal.AuthenticationContext.acquireTokenAfterValidation(AuthenticationContext.java:1229) at com.microsoft.aad.adal.AuthenticationContext.acquireTokenLocalCall(AuthenticationContext.java:1123) at com.microsoft.aad.adal.AuthenticationContext.refreshToken(AuthenticationContext.java:1609) at com.microsoft.aad.adal.AuthenticationContext.localFlow(AuthenticationContext.java:1261) at com.microsoft.aad.adal.AuthenticationContext.acquireTokenAfterValidation(AuthenticationContext.java:1229) at com.microsoft.aad.adal.AuthenticationContext.acquireTokenLocalCall(AuthenticationContext.java:1123) at com.microsoft.aad.adal.AuthenticationContext.refreshToken(AuthenticationContext.java:1609) at com.microsoft.aad.adal.AuthenticationContext.localFlow(AuthenticationContext.java:1261) at com.microsoft.aad.adal.AuthenticationContext.acquireTokenAfterValidation(AuthenticationContext.java:1229) at com.microsoft.aad.adal.AuthenticationContext.acquireTokenLocalCall(AuthenticationContext.java:1123) at com.microsoft.aad.adal.AuthenticationContext.access$600(AuthenticationContext.java:58) at com.microsoft.aad.adal.AuthenticationContext$4.call(AuthenticationContext.java:1072) at com.microsoft.aad.adal.AuthenticationContext$4.call(AuthenticationContext.java:1067) at java.util.concurrent.FutureTask.run(FutureTask.java:237)
Версия библиотеки AzureAD, которую я использую: 1.1.7 (чтобы не обвинять слишком старую версию - я проверил список изменений с 1.1.7 по 1.1.11 и не нашел ничего, связанного с вопросом)
Проблема: сейчас я рассматриваю эту ошибку как сигнал, через который пользователь переходит на экран входа в систему. На мой взгляд, это ухудшает восприятие пользователем. Тот факт, что это происходит очень часто и затрагивает многих пользователей, еще больше усугубляет ситуацию.
Вопрос: Могу ли я что-то сделать, чтобы избежать AuthenticationException
этой ошибки или как-то ее обойти (т. е. избежать повторного ввода учетных данных пользователем).
acquireTokenSilentSync()
правильным методом. Что ж. Это то, что я хочу выяснить. Некоторое время (недели?) Все работает нормально. (Я делаю этот вызов, чтобы получить токен для каждого внутреннего запроса). Потом он истекает. Мое внутреннее ощущение - это слишком быстро истекает. - person Konstantin Loginov   schedule 06.01.2016