Как создать «виртуальную» или «временную» роль для пользователя в ASP.NET MVC 5, которая все еще будет работать с украшениями контроллера и метода? - PullRequest
0 голосов
/ 14 сентября 2018

Текущий проект:

Я немного озадачен тем, как создать «виртуальную» роль под MVC 5.

Нормальные (постоянные) роли, которые я полностью понимаю: вы создаете их в БД изатем назначьте пользователя на эту роль.Однако мне нужно назначить пользователя на «Роль» в зависимости от состояния в полностью несвязанной таблице и от того, где эта Роль существует только во время их сеанса - она ​​не существует для этого пользователя до входа в систему и больше не существуетдля этого пользователя, как только его сеанс заканчивается.

Так, например, поскольку статус Active зависит от того, находится ли пользователь в отпуске или нет, давайте назовем эту таблицу таблицей «в отпуске».Очень просто: первичный ключ, внешний ключ идентификатора пользователя, требуемая дата начала и необязательная дата окончания.Когда пользователь входит в систему, мне нужно пометить пользователя как полностью активного (фактическая активная роль только для этого сеанса) или неактивного (без активной роли для этого сеанса).Это будет зависеть от того,

  1. есть ли у пользователя запись в таблице «в отпуске», и если да,
  2. для самой последней записи,
    1. Нулевая дата окончания или
    2. конечная дата в будущем

Если у пользователя есть запись в таблице, а самая последняя запись имеетнулевая конечная дата или конечная дата в будущем, пользователь не получает активную роль.Если они не удовлетворяют этому требованию, они получают эту роль.

Это лишь одно из требований к сайту, требующих виртуальных ролей, но упрощенный пример получения

Это также очень важно, потому что примерно 95-99% моих потребностей вращается вокруг контроллера и декораций методов и авторизации сеансов - мне нужно иметь возможность [Authorize(Roles = "Active")] иUser.Identity.IsInRole("Active"), но я хочу, чтобы эта роль существовала для пользователя только для этого сеанса .

Пожалуйста, поймите, что базовые данные являются полностью динамическими: если данные на серверной части изменяются начто-то, что делает их недействительными для статуса Active, я хочу, чтобы их следующий логин не включал активную роль, применяемую к их сеансу. Именно по этой я пытаюсь работать с «виртуальной» или «временной» ролью, с которой пользователь не непосредственно связан с точки зрения данных в БД.

Теперь, если проверяется только одна вещь (например, таблица «При выходе»), я могу просто гарантировать, что добавление даты окончания добавит пользователя в полностью традиционную активную роль, нопроблема существует для записей в будущем - как бы я мог обойти автоматическое добавление пользователя к этой роли после того, как эта дата пройдет, по крайней мере без выполнения базы данных write-and-login-bounce для правильной установки их аутентификации и переменных сеанса?

Плюс, это всего лишь один из многих пунктов, которые должны работать согласованно, чтобы определить «да» или «нет» для статуса «Активный».Этот активный статус будет получен не из , а просто самой последней записи таблицы «При выходе», но также из ряда различных бизнес-правил со всей системы, которые могут быть извлечены из исходногоизвлечение профиля пользователя через _userManager, и все они являются виртуальными логическими значениями, обеспечивающими простой кумулятивный ответ "да-нет".

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

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

Если кто-то может бросить приветНет информации о том, как установить там виртуальную роль, с которой может работать система (декорации контроллера и метода), что было бы очень здорово.


В соответствии с запросом, моя логин реализации:

var user = await _userManager.FindAsync(model.Username, model.Password);
if(user != null) {
  SignInAsync(user, false).Wait();
  // Bounce the user to the "Nexus" method, that determines where they should go based on Role, so that the Role can actually be read once it is in the User’s context.
}

И моя SignInAsync() Задача:

private async Task SignInAsync(IdentityUser user, bool isPersistent) {
  AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
  var identity = await _userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
  identity.AddClaim(new UserClaim.Claim("ShortName", user.ShortName));
  identity.AddClaim(new UserClaim.Claim("Name", user.Name));
  // Snipped for brevity
  AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

1 Ответ

0 голосов
/ 15 сентября 2018

Похоже, что Microsoft собирается авторизоваться на Claims. В ASP.NET Identity существуют роли для обратной совместимости.

Однако вы все равно можете установить роль в качестве претензии. Например,

claims.Add(new Claim(ClaimTypes.Role, "Admin"));

Затем вы применяете атрибут Authorize к контроллеру или методу действия как [Authorize(Roles = "Admin")]

Здесь - это пример кода на GitHub.

...