首页 > 解决方案 > 使用 AcquireTokenSilentAsync 通过 Persisted TokenCache 重新进行身份验证

问题描述

我有一个场景,其中 3 种不同类型的客户端(设备类型)预计能够通过 Azure AD 对我的 Web 应用程序进行身份验证。但是,只有在第一种类型(PC 环境中的普通浏览器)中,才会要求用户插入他们的 Azure AD 用户名和密码才能登录。我的想法是创建某种只需要使用 Azure AD 登录的过程用户名和密码第一次。用户将使用第一种类型的客户端进行首次登录,但此后该过程也可以在没有用户名和密码的情况下工作;相反,用户将能够通过用户名 + 密码甚至智能卡登录来访问系统。

经过一番研究,“刷新令牌”一词似乎经常出现。似乎最新版本的 ADAL不再提供物理刷新令牌;因此实际的刷新令牌无法保存在某些数据库中,然后在从类型 2 或类型 3 设备登录时使用。但是,同一篇文章还建议此刷新令牌现在由 ADAL 在缓存中自动处理。

我还发现了一些很棒的示例代码,它们通过实体框架在 MSSQLLocalDB 数据库中实现了持久的 ADAL 令牌缓存。

基本上我的想法是:

  1. 使用 OpenIDConnect 第一次使用用户名和密码进行身份验证,并将 TokenCache 保存在本地数据库中
  2. 下次不用用户名和密码登录时,从本地数据库中检索持久化的令牌缓存并使用
  3. AcquireTokenSilentAsync 登录,并让 ADAL 为我处理刷新令牌逻辑,就像在缓存内存场景中一样。

现在我不确定我在解决这个问题(上图)的尝试是否至少在正确的轨道上(指导我:)!),但我注意到以下代码段中使用的tenantID、SignedInUserID 和 UserObjectID 都是可检索的在第一次成功的身份验证时,这促使我至少尝试一下。

Dim clientcred As ClientCredential = New ClientCredential(aadClientId, aadAppKey)
Dim authenticationContext As AuthenticationContext = New AuthenticationContext(aadInstance & tenantId, New ADALTokenCache(SignedInUserID))
Dim authenticationResult As AuthenticationResult = Await authenticationContext.AcquireTokenSilentAsync(aadGraphResourceID, clientcred, New UserIdentifier(UserObjectID, UserIdentifierType.UniqueId))

注意:ADALTokenCache 是自定义 ADALTokenCache 类的构造函数,用于处理在本地数据库中持久化 TokenCache。

因此,我将这 3 个值保存在我的系统数据库中,然后在智能卡登录时,我通过用户名检索它们,然后使用 AcquireTokenSilentAsync,如上所示。

我已经实施了这个解决方案并且有一些问题 -

身份验证结果返回对象的片段。

1)似乎持久化的令牌是从本地数据库中检索到的,并且似乎 authenticationResult 对象确实检索到了正确的值;访问令牌、ID 令牌和用户信息!但是,似乎并没有对我进行身份验证/登录。request.IsAuthenticated 保持错误,我不知道下一步该做什么。这个过程是错误的还是我需要做更多的事情?

2) authenticationResult 似乎有一个到期日期,它始终是原始令牌创建时间的 1 小时。在我看来,这就像实际的访问令牌到期时间,但在任何 ADAL 相关对象中都看不到与刷新令牌到期相关的任何内容!所以这是一个相当棘手的情况。

3) ADAL 确实说刷新令牌是在缓存中自动处理的。但是有什么要从 Azure AD 配置端进行配置的吗?我没有发现与在 Azure 门户中设置刷新令牌或其到期详细信息相关的内容。

标签: azureauthenticationazure-active-directoryowinadal

解决方案


推荐阅读