我正在构建一个依赖AAD身份验证的ASP.NET MVC Web应用程序。我使用标准流程将auth添加到项目中(通过VS的AAD Auth),它在过去两周内完美运行。
今天,它突然被打破了:
这发生在node
初始化(标准AAD身份验证例程):
ADALTokenCache
似乎很奇怪,我不知道根本原因 - 除了添加更多视图和控制器之外没有对应用程序本身进行任何更改(没有任何应该与auth混淆)。
清除浏览器Cookie不会做任何事情。手动设置MachineKey也无济于事。
一旦部署了应用程序,就会在本地和远程服务器上进行重新调用。
以前有人遇到过这个吗?
看起来很奇怪,没有对配置进行任何修改。
答案 0 :(得分:4)
解决方法是放弃数据库。
缓存基于本地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" />
答案 1 :(得分:1)
当我收到此错误时,是因为我缓存了一些错误的登录信息,并且身份验证很难检索它,导致异常。
为了解决这个问题,我从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身份验证。单击完成以使用与先前相同的设置重新配置它。因为您注释掉了默认连接,所以它会自动为您生成一个新字符串,并使用已清除的缓存为您的成员信息创建一个新的本地数据库。
之前的解决方案对我不起作用,但确实如此!
答案 2 :(得分:1)
我遇到了同样的问题。
清除UserTokenCaches表而不是删除整个数据库。
答案 3 :(得分:0)
我相信ADALTokenCache
类的默认实现中存在一个由Visual Studio自动生成的错误。据我所知,在UNIQUE
列上没有WebUserUniqueId
约束,在从缓存中检索令牌的.OrderByDesc(t=>t.LastWriteDate)
的调用中没有.FirstOrDefault(c => c.WebUserUniqueId == userId)
,也没有清除发生的缓存。换句话说,可以针对AAD进行多次身份验证,并且每次可以将新令牌写入数据库中的UserTokenCaches
表中,但是通过调用.FirstOrDefault()
来检索令牌时,如果不进行排序,则不能确定要检索哪个版本,以及如何确定SQL Server通常如何写入数据,最有可能从表中检索最早的令牌。
此错误也可能导致 invalid_grant 消息( AADSTS70002 )指出由于不活动,刷新令牌已过期。该令牌是在...上发行的,并且对于...无效。
最快的备份和运行方法是清除数据库中的UserTokenCaches
表,并让用户针对Azure重新进行身份验证,或者至少运行DELETE UserTokenCaches WHERE LastWriteDate < ...
来摆脱一些最古老的令牌。
一种快速而肮脏的解决方法是,在创建Startup.Auth.cs
和AuthenticationContext
的代码行之前,清除位于new ADALTokenCache(...)
中的方法中用户令牌的缓存。宾语。
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
会如何影响通过EF从.Net进行的查找,因为我已经看到基于自动生成的基于WHERE
的搜索将参数提升为{{1} }而不是NVARCHAR
导致INDEX SCAN或TABLE SCAN操作而不是SEEK操作。我会手动优化该调用,其中使用VARCHAR
来确保使用正确的索引,而不是调用.FirstOrDefault(...)
。 (以下代码未经测试):
db.UserTokenCacheList.FirstOrDefault(...)