【问题标题】:ADAL: W8.1 app trying to log user outADAL:W8.1 应用程序试图注销用户
【发布时间】:2026-02-11 01:00:01
【问题描述】:

我有一个概念验证 W8.1-app,它允许使用 ADAL 库通过 Azure Active Directory 对用户进行身份验证。

我已经完成了允许用户登录和访问我的资源的工作。但是,它应该能够允许用户退出,并允许其他用户在同一设备上登录。

我在SO 和其他地方发现了关于类似问题的其他问题,但在 IOS 或 WPF 应用程序中。在那里,他们建议调用<AuthenticationContext>.TokenCache.Clear() 并使用以下调用清除cookie:

private void ClearCookies()
{
    const int INTERNET_OPTION_END_BROWSER_SESSION = 42;
    InternetSetOption(IntPtr.Zero, INTERNET_OPTION_END_BROWSER_SESSION, IntPtr.Zero, 0);
}
[DllImport("wininet.dll", SetLastError = true)]
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);

两者都不起作用(即使一起使用也不行)。 调用时

AuthenticationResult ar = await authContext.AcquireTokenAsync("https://xxx", "yyyy", new Uri("ms-app://callback/")
    , new AuthorizationParameters(PromptBehavior.Auto, true));

如果我使用 PromptBehavior.Always,用户确实必须始终验证自己,但它不使用缓存。

关于如何使令牌缓存无效的任何想法?

提前致谢

编辑:已解决

感谢 vibronet,我能够通过以下方式成功注销用户:

authContext.TokenCache.Clear();
string requestUrl = "https://login.windows.net/common/oauth2/logout";
Task.Run(async () =>
{
    var client = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
    var response = await client.SendAsync(request);
});

编辑2

您还可以通过将“common”替换为租户的别名来使用特定于您的应用程序/租户的 url,如下所示:

string tenantAlias = "TenantAlias.onmicrosoft.com";
string requestUrl = string.Format("https://login.windows.net/{0}/oauth2/logout", tenantAlias);

【问题讨论】:

  • 这对我不起作用。网络跟踪显示响应是一个充满 JavaScript 的页面,显然不会在此处运行,而且我可以看到响应设置并且没有清除 ESTSAUTH 之类的 cookie。

标签: azure windows-8.1 azure-active-directory adal


【解决方案1】:

实际的用户会话由两个不同的组件确定:令牌缓存(在 ADAL 的控制下)和系统中可能存在的任何会话跟踪 cookie(不受 ADAL 的控制)。

正如您所指出的,您可以轻松处理令牌缓存部分。但是,您提到的清除 cookie 的逻辑不适用于 Windows 应用商店应用程序。它适用于 WPF,因为对于桌面应用程序,身份验证期间使用的 cookie jar 是应用程序本身的一个。在 Windows 应用商店中,身份验证与 WebAuthenticationBroker 同步,它有自己的 cookie jar,与您的应用程序代码分开且无法访问。

最可靠的方法是不创建任何持久性 cookie(例如,在身份验证期间不单击“记住我”)。但是,如果您最终得到这样的 cookie,摆脱它的主要方法是触发从同一个 WebAuthenticationBroker 注销 - 服务器将负责清理。代码方面:

string requestUrl = "https://login.windows.net/common/oauth2/logout";
Task.Run(async () =>
{
    try
    {
        await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.SilentMode, new Uri(requestUrl));
    }
    catch (Exception)
    {
        // timeout. That's expected
    }
});

【讨论】:

  • 这不起作用,AuthenticateAsync() 方法会抛出 NotImplementedException。但是,对您指定的网址执行一个简单的 HttpRequest 就可以了 :) - 更新了原始帖子以包含您的建议和解决方案 - 谢谢 :)
  • 啊,你是对的,我为 windows 8.1 而不是 windows PHONE 8.1(其 WAB 不支持静默选项)编写了答案。我的错! :-) 但很高兴你能成功
最近更新 更多