是什么导致“ UserManager”返回错误的用户?

时间:2018-07-28 13:27:53

标签: asp.net-core asp.net-core-mvc entity-framework-core asp.net-core-2.0 entity-framework-core-2.1

我的ASP.NET Core 2.1.0 MVC网站上发生了相当恐怖的事情。当我浏览时,突然间显示我以其他用户身份登录(当时他恰巧也在浏览该网站)。

我无法确定是否有特定的用例会触发此操作,但是现在已经发生了两次。导航到其他页面仍然显示我以其他用户身份登录。似乎我还是接管了我以错误身份登录的用户的声明。

我的问题是:会发生什么?


编辑:此后,我将userManagernotificationService更改为“作用域”,并且此问题再次发生,因此这里所报告的潜在问题不可能成为原因。

尝试研究这个问题,我相信罪魁祸首可能是_Layout.cshtml中的以下电话:

@inject UserManager<ApplicationUser> userManager
@inject NotificationService notificationService
@inject CommunityService communityService
@{
    ApplicationUser user = await userManager.GetUserAsync( User );
}

返回的user用于显示用户信息并调用notificationServicecommunityService。这些还显示了与不正确(不是我)用户有关的数据。

如果有关系,可以在ApplicationDbContext中设置Startup.cs

// Add framework services.
services
    .AddDbContext<ApplicationDbContext>( options => options
        .UseLazyLoadingProxies()
        .UseSqlServer(_configuration.GetConnectionString( "DefaultConnection" ) ) );
services
    .AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

我回想起'scoped' is the recommended lifetime to use when registering Entity Framework for dependency injection。但是,NotificationServiceCommunityService都注册为“瞬态”,并通过构造函数注入请求ApplicationDbContext来访问数据。

services.AddTransient<CommunityService, CommunityService>();
services.AddTransient<NotificationService, NotificationService>();

这和它有什么关系吗?目前,我不知道这是否会有所作为。我似乎无法复制这个问题。

1 个答案:

答案 0 :(得分:1)

好消息!我是我自己造成的(我相信,请阅读下面的详细信息以帮助我解决此问题)。因此,您可以放心,除非您犯了与我相同的错误,否则不要责怪ASP MVC身份验证机制(至少,这是我目前的理解)。

由于其他人可能会犯同样的错误,因此我将记录我究竟在做错什么以及如何复制。

简而言之:我以“错误的”用户(最终以该用户身份登录)致电SignInManager<TUser>.RefreshSignInAsync(TUser),导致我以该用户身份登录。

为什么要这样做?在我的特定用例中,我想根据当前登录用户的操作向其他用户发出声明。因此,我打电话给了:

await _userManager.AddClaimAsync( userToGiveClaim, newClaim );
await _signInManager.RefreshSignInAsync( userToGiveClaim );

我之所以打电话给RefreshSignInAsync,是因为我想避免获得该声明的用户必须注销并重新登录才能使新的声明生效。从the RefreshSignInAsync documentation中,我得到了这样的印象:

  

重新生成用户的应用程序cookie,同时保留   现有的AuthenticationProperties(如RememberMe)作为异步对象   操作。

     

参数   用户应刷新其登录Cookie的用户。

我仍然不太清楚为什么触发此调用时当前登录的用户会获得传递给此调用的用户的身份。这仍然不是我理解文档(I filed this as a bug report)的方式,但是由于这是可复制的,因此我现在更倾向于相信我只是误解了文档。