Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AzureAD for Android抛出ADALError.AUTH\u刷新\u失败\u提示\u不允许\u_Android_Office365_Adal_Azure Active Directory - Fatal编程技术网

AzureAD for Android抛出ADALError.AUTH\u刷新\u失败\u提示\u不允许\u

AzureAD for Android抛出ADALError.AUTH\u刷新\u失败\u提示\u不允许\u,android,office365,adal,azure-active-directory,Android,Office365,Adal,Azure Active Directory,我有一个应用程序,其中用户在Office365中通过身份验证 它运行良好,用户可以认证和使用该应用程序。不幸的是,过了一段时间后,他们开始使用

我有一个应用程序,其中用户在Office365中通过身份验证

它运行良好,用户可以认证和使用该应用程序。不幸的是,过了一段时间后,他们开始使用
进行命中

我查了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.
        }
    }
    ..............
} 
我得到的是:

.data\u access.error\u handler.AuthenticationExceptionWithServiceInfo:刷新令牌失败,不允许提示
位于com.microsoft.aad.adal.AuthenticationContext.localFlow(AuthenticationContext.java:1294)
位于com.microsoft.aad.adal.AuthenticationContext.acquireTokenAfterValidation(AuthenticationContext.java:1229)
位于com.microsoft.aad.adal.AuthenticationContext.acquireTokenLocalCall(AuthenticationContext.java:1123)
位于com.microsoft.aad.adal.AuthenticationContext.refreshToken(AuthenticationContext.java:1609)
位于com.microsoft.aad.adal.AuthenticationContext.localFlow(AuthenticationContext.java:1261)
位于com.microsoft.aad.adal.AuthenticationContext.acquireTokenAfterValidation(AuthenticationContext.java:1229)
位于com.microsoft.aad.adal.AuthenticationContext.acquireTokenLocalCall(AuthenticationContext.java:1123)
位于com.microsoft.aad.adal.AuthenticationContext.refreshToken(AuthenticationContext.java:1609)
位于com.microsoft.aad.adal.AuthenticationContext.localFlow(AuthenticationContext.java:1261)
位于com.microsoft.aad.adal.AuthenticationContext.acquireTokenAfterValidation(AuthenticationContext.java:1229)
位于com.microsoft.aad.adal.AuthenticationContext.acquireTokenLocalCall(AuthenticationContext.java:1123)
位于com.microsoft.aad.adal.AuthenticationContext.access$600(AuthenticationContext.java:58)
位于com.microsoft.aad.adal.AuthenticationContext$4.call(AuthenticationContext.java:1072)
位于com.microsoft.aad.adal.AuthenticationContext$4.call(AuthenticationContext.java:1067)
位于java.util.concurrent.FutureTask.run(FutureTask.java:237)
我正在使用的AzureAD库的版本:1.1.7(为了避免归咎于太旧的版本-我已经检查了从1.1.7到1.1.11的变更列表,没有发现任何与问题相关的内容)

问题:现在,我将此错误视为通过用户发送到登录屏幕的信号。在我看来,这会导致用户体验不佳。这种情况经常发生,并且影响到许多用户,这一事实使情况更加糟糕


问题:我可以做些什么来避免此
身份验证异常
或以某种方式解决它(即避免用户再次输入凭据).

这是因为您需要刷新您的令牌并在代码中实现它,这样用户就不会在每次访问令牌过期时都被提示登录。请在此处查看如何实现刷新令牌:


希望这有帮助。

您是否验证了
AuthenticationContext.acquireTokenSilentSync()
确实是您希望调用的方法

文档表明此方法不会显式显示提示。从文档中:

This is sync function. It will first look at the cache and automatically checks for the token expiration. Additionally, if no suitable access token is found in the cache, but refresh token is available, the function will use the refresh token automatically. This method will not show UI for the user. If prompt is needed, the method will return an exception.
您获得的刷新令牌每年应持续两周。刷新令牌过期后,用户需要重新验证。你能和Fiddler或Charles一起检查网络流量并检查代币的有效期吗?如果您可以验证令牌在到期前未能刷新,则可能表明AD库中存在错误

要澄清
AuthenticationContext
上方法的差异,有两类方法:“静默”方法(在需要重新验证时不会向用户显示对话框)和非静默方法。如果需要用户重新验证(或同意),非静默方法将启动包含AAD登录的新活动。此时,身份验证流将重新启动


此外,如果您对应用程序在Azure中的注册进行更改,例如添加新的权限范围,则您的用户将需要重新授予许可,应用程序才能继续处理其数据

@iambmelton我在用密码处理promt。所以我想知道,一旦我得到了异常,尝试显式刷新令牌是否为时已晚,或者是否有解决方法?关于
acquireTokenSilentSync()
是否是正确的方法。好。这是我想弄明白的。有一段时间(几周?)效果很好。(我这样做是为了为每个后端查询获取令牌)。然后它“到期”。我的直觉-它过期太快了。@iambmelton好的,我明白了:这是一种预期的行为,在一段时间后-2周-用户再次进入登录屏幕,没有办法阻止它。这很可悲,但还是很高兴知道!(关于silent/non-silect-yes,我之所以选择silent,是为了手动处理身份验证流,以获得输入电子邮件的良好视图(例如,在OneDrive中)。顺便说一句,如果你把你的评论转换成答案-我可以接受!发布在下面,我将清除此处的评论以删除重复信息:)
This is sync function. It will first look at the cache and automatically checks for the token expiration. Additionally, if no suitable access token is found in the cache, but refresh token is available, the function will use the refresh token automatically. This method will not show UI for the user. If prompt is needed, the method will return an exception.