检测到多个令牌的 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();
我已经在我的 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();