【问题标题】:Azure Active Directory Auth Broken - No known root causeAzure Active Directory Auth Broken - 没有已知的根本原因
【发布时间】:2018-12-23 11:26:50
【问题描述】:

我正在构建一个依赖于AAD auth 的 ASP.NET MVC Web 应用程序。我使用标准流程将身份验证添加到项目(通过 VS 进行 AAD 身份验证),并且在过去两周内运行良好。

今天突然坏了:

这发生在ADALTokenCache 初始化(标准 AAD 身份验证例程):

public ADALTokenCache(string signedInUserId)
{ 
    // associate the cache to the current user of the web app
    userId = signedInUserId;
    this.AfterAccess = AfterAccessNotification;
    this.BeforeAccess = BeforeAccessNotification;
    this.BeforeWrite = BeforeWriteNotification;
    // look up the entry in the database
    Cache = db.UserTokenCacheList.FirstOrDefault(c => c.webUserUniqueId == userId);
    // place the entry in memory
    this.Deserialize((Cache == null) ? null : MachineKey.Unprotect(Cache.cacheBits,"ADALCache"));
}

看起来很奇怪,根本原因对我来说是未知的——除了添加更多视图和控制器之外,没有对应用程序本身进行任何更改(没有什么应该与 auth 混淆)。

清除浏览器 cookie 无济于事。手动设置 MachineKey 也无济于事。

部署应用后,本地和远程服务器上都将重现。

有人遇到过这种情况吗?

在没有对配置进行任何修改的情况下出现似乎很奇怪。

【问题讨论】:

  • 听起来可能是域名更改或问题......你能显示实际代码以及你在那里拥有的堆栈跟踪吗......
  • 看起来您正在使用本地机器密钥来解密从远程 AD 返回的一些数据。是这样吗?如果是,那么如果您身边的机器密钥发生了变化,您将无法解密使用不同密钥加密的任何内容。
  • 我想知道在这种情况下是否有一个很好的方法来重置缓存。数据应通过 MachineKey 加密处理。
  • 也许只是不要通过为应用设置自定义固定键来改变键。

标签: c# asp.net-mvc azure authentication azure-active-directory


【解决方案1】:

解决方案是删除数据库。

缓存基于本地 MDF 文件,并在 Web.config 中更改其名称:

<add name="DefaultConnection" 
connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-Den-SomeNewName.mdf;Initial Catalog=aspnet-Den-SomeNewName;Integrated Security=True" 
providerName="System.Data.SqlClient" />

【讨论】:

    【解决方案2】:

    当我收到此错误时,是因为我缓存了一些错误的登录信息,而身份验证正在努力检索它,导致异常。

    为了解决这个问题,我从 SSMS 中删除了数据库,然后注释掉了这一行:

    <add name="DefaultConnection" 
    connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-Den-SomeNewName.mdf;Initial Catalog=aspnet-Den-SomeNewName;Integrated Security=True" 
    providerName="System.Data.SqlClient" /> 
    

    在 Web.config 中。

    然后右键单击您的解决方案并配置您的 Azure AD 身份验证。单击完成以使用与以前相同的设置重新配置它。因为您注释掉了默认连接,它会自动为您生成一个新字符串并为您的成员信息创建一个新的本地数据库,并清除缓存。

    以前的解决方案对我不起作用,但它确实有效!

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。

      清除 UserTokenCaches 表而不是删除整个数据库。

      【讨论】:

      • 我试过你的方法。一切似乎对我有用,但对其他用户却没有。那我该怎么办?
      【解决方案4】:

      我相信 ADALTokenCache 类的默认实现中存在由 Visual Studio 自动生成的错误。据我所知,WebUserUniqueId 列上没有UNIQUE 约束,在从缓存中检索令牌的.FirstOrDefault(c =&gt; c.WebUserUniqueId == userId) 调用中没有.OrderByDesc(t=&gt;t.LastWriteDate),也没有清除缓存。换句话说,可以针对 AAD 进行多次身份验证,并且每次可以将新令牌写入数据库中的 UserTokenCaches 表,但是当调用 .FirstOrDefault() 以检索令牌而不进行排序时,它不确定检索哪个版本,以及 SQL Server 通常如何写入数据,更有可能从表中检索最旧的令牌。

      此错误还可能导致 invalid_grant 消息 (AADSTS70002) 指出 刷新令牌由于不活动而过期。令牌于 ... 发行,并且在 ...

      期间处于非活动状态

      恢复并运行的最快方法是清除数据库中的 UserTokenCaches 表并让您的用户针对 Azure 重新进行身份验证,或者至少运行 DELETE UserTokenCaches WHERE LastWriteDate &lt; ... 以删除一些最旧的令牌。

      对此的快速而肮脏的解决方法是在创建AuthenticationContextnew ADALTokenCache(...) 对象的代码行之前清除位于Startup.Auth.cs 中的方法中的用户令牌缓存。

      db.UserTokenCacheList.RemoveRange(db.UserTokenCacheList.Where(t => t.webUserUniqueId == signedInUserID));
      db.SaveChanges();
      

      UserTokenCaches 表的默认实现可能存在可伸缩性问题,以及它的构造方式。 webUserUniqueId 的默认类型是NVARCHAR(MAX),并且不能在其上放置UNIQUE 或索引约束。我建议将类型更改为 VARCHAR 并且长度可以正确保存该值,并在此列上创建单个 UNIQUE CLUSTERED 索引,因为 cacheBits 列不能包含在小的覆盖索引中。最好也限制 cacheBits 列的大小,尽管我不知道这个或 webUserUniqueId 列可以增长多大。我也不知道数据类型从NVARCHAR 更改为VARCHAR 是否会影响从.Net 到EF 的查找,因为我已经看到自动生成的基于WHERE 的搜索将参数提升为NVARCHAR 而不是VARCHAR 导致INDEX SCAN 或 TABLE SCAN 操作而不是 SEEK 操作。我不会调用.FirstOrDefault(...),而是手动优化使用db.UserTokenCacheList.FirstOrDefault(...) 的调用,以确保使用正确的索引。 (以下代码未经测试):

      Cache = db.UserTokenCacheList.SqlQuery("SELECT * FROM UserTokenCacheList WHERE webUniqueUserId = @webUniqueUserId;", new System.Data.SqlClient.SqlParameter("@webUniqueUserId", System.Data.SqlDbType.VarChar({Value=signedInUserID}).FirstOrDefault();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多