检测到多个令牌的 Azure Active Directory 单点登录问题

Azure Active Directory Single Sign On Multiple tokens detected Issue

我已经在我的 Windows 8.1 商店应用程序中实施了 Azure Active Directory。

第一次打开该应用程序时,它会打开 AAD 登录弹出窗口,用户将输入电子邮件和密码,然后登录到该应用程序,为此我正在使用下面的代码,它工作正常。

    AADLoginFirstTime()
{

AuthenticationContext ac = new AuthenticationContext(App.authority);
                    AuthenticationResult ar = await ac.AcquireTokenAsync(App.resourceURI, App.clientID, (Uri)null,PromptBehavior.Always);
                    JObject payload = new JObject();
                    payload["access_token"] = ar.AccessToken;
                    user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);

//saving user token into vault
credential = new PasswordCredential(provider,
                            user.UserId, user.MobileServiceAuthenticationToken);
                        vault.Add(credential);

}

从第二次开始我使用调用下面的代码行

    AADLoginSecondTime()

{

AuthenticationContext ac = new AuthenticationContext(App.authority);
                        AuthenticationResult ar = await ac.AcquireTokenAsync(App.resourceURI, App.clientID, (Uri)null);
                        JObject payload = new JObject();
                        payload["access_token"] = ar.AccessToken;
                        user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);

}

区别在于从第二次开始,LoginAsync 方法没有提示行为。

这对单用户来说工作正常。

为了注销,我只是将页面导航到登录屏幕并调用 AADLoginFirstTime() 方法来显示登录弹出窗口。

如果我使用另一个用户 AAD 凭据并登录到应用程序,当它提示登录弹出窗口时,从下次打开应用程序并现在调用 AADLoginSecondTime() 方法,应用程序将抛出一个名为移动服务无效令牌的异常。

AuthenticationResult ar = await ac.AcquireTokenAsync(App.resourceURI, App.clientID, (Uri)null);

此方法returns一个空标记。

这是否是因为之前的用户没有从应用程序中完全退出?如果是,我怎样才能完全注销以前的用户?

每次您使用 ADAL 获得令牌时,它(连同许多其他内容)将保存在持久缓存中。如果你想刷新那个缓存,你可以调用 ac.TokenCache.Clear()。如果您想删除特定用户的令牌,您可以 运行 对缓存进行 LINQ 查询并删除特定项目。请注意,这完全独立于移动服务。

当用户首次使用 AAD 登录屏幕登录应用程序时,成功登录后 AAD 将 return 用户的 UniqueId。 现在我们将在应用程序的 LocalSettings 中保存用户的唯一 ID。

       AADLoginFirstTime()
    {
     AuthenticationContext ac = new AuthenticationContext(App.authority);
                        AuthenticationResult ar = await ac.AcquireTokenAsync(App.resourceURI, App.clientID, (Uri)null,PromptBehavior.Always);
                        JObject payload = new JObject();
                        payload["access_token"] = ar.AccessToken;
                        user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);

                        Windows.Storage.ApplicationData.Current.LocalSettings.Values["AADUniqueId"] = ar.UserInfo.UniqueId;
}

下次打开应用程序时,我们会将用户的唯一 ID 传递给 AAD AcquireTokenAsync() 方法,如下所示

AADLoginSecondTime()
{
    UserIdentifier userIdent = new UserIdentifier(AADUniqueId, UserIdentifierType.UniqueId);                       
                        AuthenticationContext ac = new AuthenticationContext(App.authority);
                        AuthenticationResult ar = await ac.AcquireTokenAsync(App.resourceURI, App.clientID, (Uri)null,PromptBehavior.Never, userIdent);
                        JObject payload = new JObject();
                        payload["access_token"] = ar.AccessToken;
                        user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
}

AAD 在缓存中搜索具有 UniqueId 的用户并在后台使用 AAD 验证该用户并导航到登录页面。

仅当您要维护用户缓存时,才首选此解决方案。 否则在用户从应用程序注销时清除缓存。

ac.TokenCache.Clear();