Что может привести к тому, что UserManager вернет не того пользователя?

Что-то довольно страшное происходит на моем сайте ASP.NET Core 2.1.0 MVC. В то время как я просматривал, внезапно он показывает, что я вошел в систему как другой пользователь (который также случайно просматривал сайт в то время).

Я не могу точно определить, есть ли конкретный вариант использования, который вызывает это, но это уже дважды происходило. Переход на другие страницы по-прежнему показывает, что я вошел как другой пользователь. Даже кажется, что я беру на себя претензии пользователя, которого я неправильно вошел как.

Мой вопрос: что могло бы сделать это?


РЕДАКТИРОВАТЬ: я с тех пор изменился userManager а также notificationService в "область действия", и эта проблема возникла снова, поэтому потенциальная проблема, о которой здесь сообщается, не может быть причиной.

Пытаясь разобраться в этом, я считаю, что виновником может быть следующий вызов в _Layout.cshtml:

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

Возвращенный user используется для отображения информации о пользователях и выполнения вызовов notificationService а также communityService, Они также показывали данные, относящиеся к неправильному (не мне) пользователю.

Если это имеет значение, это как ApplicationDbContext настроен в Startup.cs:

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

Я вспомнил, что "scoped" - это рекомендуемое время жизни для использования при регистрации Entity Framework для внедрения зависимостей. И то и другое NotificationService а также CommunityServiceоднако, зарегистрированы как "переходные" и запрос ApplicationDbContext через конструктор для доступа к данным.

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

Может ли это иметь какое-либо отношение к этому? В настоящее время я не понимаю, может ли это иметь какое-либо значение. Я не могу воспроизвести эту проблему.

1 ответ

Решение

Хорошие новости! Я сам вызывал это(я думаю, помогите мне разобраться, прочитав подробности ниже). Таким образом, вы можете быть уверены, что если вы не совершаете ту же ошибку, что и я, то здесь не виноват механизм аутентификации ASP MVC (по крайней мере, это мое нынешнее понимание).

Я документирую, что именно я сделал неправильно, и как его воспроизвести, поскольку другие могут совершить ту же ошибку.

Короче говоря: я звонилSignInManager<TUser>.RefreshSignInAsync(TUser) с "неправильным" пользователем (тем, к которому я подключился как), в результате чего я вошел как этот пользователь.

Почему я это сделал? В моем конкретном случае использования я хотел раздать претензию другому пользователю, основываясь на действиях текущего пользователя, вошедшего в систему. Я поэтому назвал:

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

я звонил RefreshSignInAsync так как я хотел предотвратить выход пользователя из системы, которому была выдана претензия, и вступление новой претензии в силу. Из RefreshSignInAsync По документации у меня сложилось впечатление, что это должно работать:

Восстанавливает cookie-файл приложения пользователя, сохраняя существующие свойства AuthenticationProperties, такие как RememberMe, в качестве асинхронной операции.

Параметры user Пользователь, чей файл cookie для входа должен быть обновлен.

Я до сих пор не совсем понимаю, почему пользователь, который в данный момент вошел в систему, когда этот вызов инициирован, получает личность пользователя, переданного этому вызову. Я до сих пор не понимаю документацию ( я подал это как отчет об ошибке), но, поскольку это воспроизводимо, я теперь более склонен полагать, что я просто неправильно понял документацию.