ADAL AcquireToken Windows 身份验证 UWP

Posted

技术标签:

【中文标题】ADAL AcquireToken Windows 身份验证 UWP【英文标题】:ADAL AcquireToken Windows authentication UWP 【发布时间】:2018-12-22 01:39:52 【问题描述】:

我正在开发一个 UWP 应用,该应用需要针对本地 ADFS 2016 实例进行身份验证,但使用的是 Windows 集成身份验证。

我正在使用 ADAL 3.19.8。 该应用程序在已加入域的 Windows 10 设备上运行。 该应用程序启用了企业身份验证、专用网络(客户端和服务器)和共享用户证书功能,如下所述:https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/uwp-specificities

我将 UseCorporateNetwork 标志设置为 true。 在 Internet 选项中启用了 Windows 集成身份验证,并且我已将 ADFS 服务器添加到本地 Intranet 区域。

这是我尝试进行身份验证的方式:

string authority = "https://xxxx/adfs/oauth2";
const bool useCorporateNetwork = true;
var authContext = new AuthenticationContext(authority, false);
var authResult = await authContext.AcquireTokenAsync(
        resourceURI, 
        clientID, 
        new Uri(clientReturnURI), 
        new PlatformParameters(PromptBehavior.Auto, useCorporateNetwork));

针对 ADFS 的身份验证成功,我获得了访问和 ID 令牌。但是,该应用程序始终显示 ADFS 登录屏幕。要继续,我输入用于登录 Windows 的相同用户名和密码凭据。显然,这并不理想,也不是应用用户希望看到的行为。

使用 Fiddler 我看到 UWP 应用调用 https://xxxx/adfs/oauth2/authorize。

如果我在 WinForms 应用程序中使用上述代码,我可以获得我期望的 SSO 行为(尽管没有 useCorporateNetwork 重载)。 使用 Fiddler,WinForms 应用调用 https://xxxx/adfs/oauth2/authorize/wia

我错过了什么?

【问题讨论】:

【参考方案1】:

如果ADAL.NET 已为用户获取 Web API 的令牌,它会将其与刷新令牌一起缓存。下次应用需要令牌时,它可以先调用AcquireTokenSilentAsync 来验证缓存中是否有可接受的令牌。

AuthenticationContext ac = new AuthenticationContext(authority);
AuthenticationResult result=null;
try

 result = await ac.AcquireTokenSilentAsync(resource, clientId);

catch (AdalException adalException)

 if (adalException.ErrorCode == AdalError.FailedToAcquireTokenSilently
     || adalException.ErrorCode == AdalError.InteractionRequired)
  
   result = await ac.AcquireTokenAsync(resource, clientId, redirectUri,
                                       new PlatformParameters(PromptBehavior.Auto));
  

更多信息请参考this。

【讨论】:

静默获取令牌总是会抛出异常,直到我通过 AcquireTokenAsync 方法成功进行身份验证。问题是对 AcquireTokenAsync 的调用显示了一个询问凭据的对话框:我希望它使用集成 Windows 身份验证,即没有对话框。 是的,如果您已经通过AcquireTokenAsync方法成功验证,您可以在下次调用AcquireTokenSilentAsync进行验证。它不会显示对话框,请确保您的应用程序不会在下次启动时被清除。 注意,您需要取消选中卸载,然后重新安装我的 Visual Studio 包选项。【参考方案2】:

我错过的一点是您需要从 WebAuthenticationBroker 获取客户端重定向 Uri,而不是将其设置为任意字符串:

Uri clientReturnURI = Windows.Security.Authentication.Web
    .WebAuthenticationBroker.GetCurrentApplicationCallbackUri();

这会返回一个 URI,例如 ms-app://s-1-15-2-1352796503-54529114-405753024-3540103335-3203256200-511895534-1429095407/,这需要在 ADFS 中针对本机应用程序进行注册。

这篇文章很有帮助:https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/Acquiring-tokens-interactively---Public-client-application-flows

这是相关部分:

特定于 WinRT 和 UWP(企业网络)的 PlatformParameter 属性

WinRT(直到 ADAL 3.x)和 UWP 平台具有以下属性 UseCorporateNetwork 是一个布尔值,它使 Win8.1 和 UWP 应用程序能够受益于 Windows 集成身份验证(因此用户使用操作系统),如果此用户使用联合 Azure AD 租户中的帐户登录。这利用了 WAB(Web 身份验证代理)。

重要提示:将此属性设置为 true 假定应用程序开发人员已在应用程序中启用 Windows 集成身份验证 (WIA)。为此:

在 UWP 应用程序的 Package.appxmanifest 中,在“功能”选项卡中,启用以下功能: 企业认证 专用网络(客户端和服务器) 默认情况下不启用共享用户证书 WIA,因为请求企业身份验证或共享用户证书功能的应用程序需要更高级别的验证才能被 Windows 应用商店接受,并且并非所有开发人员都可能希望执行更高级别的验证。 请注意,在启用了条件访问的企业方案中,UWP 平台 (WAB) 上的基础实现无法正常工作。症状是用户尝试使用 Windows hello 登录,并建议选择证书,但找不到 pin 的证书,或者用户选择了它,但从未提示输入 pin。一种解决方法是使用另一种方法(用户名/密码+电话认证),但体验不佳。未来,ADAL 和 MSAL 将需要利用 WAM,这将解决问题。

在 windows 8.1 商店应用程序的情况下获取重定向 URI

注意:对 Win8.1 和 Windows Phone 8.1 的支持在 ADAL 4.x 中停止。仍支持 Windows 10 应用程序 (UWP)

对于 Windows 商店应用程序,您需要发现 Windows Phone 应用程序的回调 uri。最简单的方法是在 Initialization 方法中添加一行(例如在 MainPage 中),并在方法中的该行设置断点:

var redirectURI = Windows.Security.Authentication.Web.WebAuthenticationBroker.GetCurrentApplicationCallbackUri();

然后,运行应用程序,并在遇到断点时复制 redirectUri 的值。它应该类似于 ms-app://s-1-15-2-1352796503-54529114-405753024-3540103335-3203256200-511895534-1429095407/ 返回 Azure 门户中应用程序的 ReplyURLs 选项卡,添加此值。

希望这对遇到同样问题的其他人有用!

【讨论】:

以上是关于ADAL AcquireToken Windows 身份验证 UWP的主要内容,如果未能解决你的问题,请参考以下文章

MS ADAL 离子 Cordova 插件

找不到方法:AcquireToken(System.String, Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCer

AcquireToken(string resource, string clientId, UserCredential userCredential) 不适用于 Azure 身份验证

如何从iOS ADAL身份验证LogOut?

ADAL 和 MSAL 混淆

AquireTokenAsync 与旧访问令牌 ADAL