Как идентифицировать пользователя, когда клиент звонит? - PullRequest
0 голосов
/ 11 марта 2020

У меня есть пользовательская проверка подлинности ie. Я думаю, что я также могу получить авторизацию на стороне сервера. Проблема у меня с авторизацией на стороне клиента. (IE: как клиент узнает, что можно или нельзя получить к нему доступ?)

Так, например, скажем, есть функция, доступная только некоторым пользователям. В моих пользовательских данных у меня может быть флаг, который указывает, какие пользователи могут или не могут получить доступ к этой функции. Затем я могу установить значение роли при входе в систему, указывая, что пользователи, которые могут получить доступ к этой функции, принадлежат к определенной роли. Затем я могу установить атрибут Authorize в методе обработчика, чтобы сказать, что только пользователи с этой ролью могут получить доступ к этому обработчику.

Это предотвращает вызов этого обработчика неавторизованными пользователями (теоретически; мне еще предстоит проверить это, но, похоже, вроде бы должно работать). Но на стороне клиента, где я создаю пользовательский интерфейс, как я могу узнать, добавлять ли эту функцию в пользовательский интерфейс или нет?

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

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

Кажется, что это именно то, что значение Authentication Cook ie для. И действительно, насколько я знаю, он отправляется уже с каждым запросом. Так что все, что мне нужно сделать, это получить это значение на стороне сервера, один раз при входе в систему, чтобы я мог вспомнить, какой auth cook ie связан с каким пользователем (и поэтому может или не может получить доступ к определенным функциям), а затем получить его по будущим вызовам AJAX, чтобы сравнить с базой данных пользователей.

Итак, вопрос в том, как мне получить это значение? Я думаю, что я могу извлечь его из будущего запроса через что-то вроде:

var authKey = HttpContext.Request.Cookies[MyAuthCookieName];

Но как я помню его, когда он генерируется? Видимо я не могу прочитать ответные куки; они могут быть только добавлены или удалены. Как получить уникально идентифицирующее значение от auth cook ie, когда оно генерируется? Это должно быть что-то вроде этого, но это не работает:

var claims = new List<Claim> {
   new Claim(ClaimTypes.Name, username)
};

if (canAccessFeature)
   claims.Add(
      new Claim(ClaimTypes.Role, "FeatureRole")
   );

var identity = new ClaimsIdentity(
   claims,
   CookieAuthenticationDefaults.AuthenticationScheme
);

var principal = new ClaimsPrincipal(identity);

await HttpContext.SignInAsync(
   CookieAuthenticationDefaults.AuthenticationScheme,
   principal,
   new AuthenticationProperties {
      IsPersistent = true
   }
);

var cookie = HttpContext.Response.Cookies[MyAuthCookieName]; // ERROR: cannot index

1 Ответ

1 голос
/ 11 марта 2020

Хорошо, я понял, что могу получить доступ к пользовательской информации через свойство User в PageModel. Вы можете использовать метод IsInRole, чтобы проверить, добавили ли вы пользователя в роль.

Вместо того, чтобы сохранять информацию на стороне клиента, вы можете просто иметь обработчик, который сообщает вам, находитесь ли вы в роли, так что клиент может знать, создавать ли пользовательский интерфейс так или иначе:

public IActionResult OnGetCanUseFeature() =>
   new JsonResult(
      User.IsInRole("FeatureRole")
   );

Для защиты фактического обработчика обратите внимание, что атрибут [Authorize] не работает на страницах Razor на уровне обработчика. Но вы можете просто спросить, находится ли пользователь в роли, и может вернуть результат статуса 403, если нет:

public IActionResult OnPostRestrictedFeature() {
   if (!User.IsInRole("FeatureRole"))
      return new StatusCodeResult(403);

   ...
...