Является ли настройка роли в JWT лучшей практикой?

Я рассматриваю возможность использования JWT. В примере jwt.io я вижу следующую информацию в данных полезной нагрузки:

"admin": true

Админ можно считать ролью, отсюда и мой вопрос. Является ли установка роли в полезной нагрузке токена привычной/хорошей практикой? Учитывая, что роли могут быть динамически изменены, я довольно вопросительный.

Ответ 1

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

Однако я бы полагался только на JWT только для аутентификации (кто звонит). Если вам необходимо выполнить авторизацию (что может сделать вызывающий абонент), найдите роли/разрешения вызывающего абонента из вашего постоянного хранилища, чтобы получить самое обновленное значение.

Ответ 2

Официальный сайт JWT явно упоминает "авторизацию" (в отличие от "аутентификации") как сценарий использования для JWT:

Когда следует использовать веб-токены JSON? Авторизация: Это наиболее распространенный сценарий использования JWT. Как только пользователь вошел в систему, каждый последующий запрос будет включать JWT, позволяющий пользователю получать доступ к маршрутам, службам и ресурсам, которые разрешены с этим токеном. Единая регистрация - это функция, которая в настоящее время широко использует JWT из-за ее небольших накладных расходов и способности легко использоваться в разных доменах.

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

(Текст ниже можно понять как более "углубленное" продолжение довольно краткого принятого ответа)

После того как вы создали и подписали токен, вы предоставляете разрешение до истечения срока его действия. Но что, если вы предоставили права администратора случайно? Пока не истечет срок действия токена, на вашем сайте кто-то работает с разрешениями, которые были назначены по ошибке.

Некоторые люди могут утверждать, что токен недолговечен, но это не сильный аргумент, учитывая количество вреда, которое человек может нанести за короткое время. Некоторые другие люди рекомендуют поддерживать отдельную таблицу базы данных черного списка для токенов, которая решает проблему аннулирования токенов, но добавляет некоторый вид отслеживания состояния сеанса к бэкэнду, потому что теперь вам нужно отслеживать все текущие сеансы, которые там существуют. - таким образом, вам придется делать db-вызов в черный список каждый раз, когда поступает запрос, чтобы убедиться, что он еще не занесен в черный список. Кто-то может возразить, что в первую очередь это противоречит цели "помещения ролей в JWT, чтобы избежать лишнего вызова db", поскольку вы просто обменяли дополнительные "роли db-call" на дополнительный "черный список вызова db"..

Таким образом, вместо добавления утверждений об авторизации в токен, вы можете хранить информацию о пользовательских ролях и разрешениях в вашей базе данных auth-server, над которыми у вас есть полный контроль в любое время (например, чтобы отозвать определенное разрешение для пользователя). Если приходит запрос, вы выбираете текущие роли с сервера авторизации (или где бы вы ни хранили свои разрешения).

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

Таким образом, в итоге вы можете...

  • добавьте роли в свой JWT, если (а) удобство важно для вас и (б) вы хотите избежать дополнительных обращений к базе данных для получения разрешений, и (в) не заботитесь о небольших временных окнах, в которых у человека есть права, назначенные ему. не должны иметь и (d) вас не волнует (небольшое) увеличение полезной нагрузки JWT в результате добавления разрешений.

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

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

Ответ 3

Как указано здесь, ASP.NET Core автоматически обнаружит любой roles, упомянутый в JWT:

{
  "iss": "http://www.jerriepelser.com",
  "aud": "blog-readers",
  "sub": "123456",
  "exp": 1499863217,
  "roles": ["Admin", "SuperUser"]
}

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

[Authorize(Roles = "Admin")]
public class SettingsController : Controller

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