Как аутентифицировать веб-токены JSON (JWT) в разных API? - PullRequest
3 голосов
/ 28 марта 2019

Я создал Rest API на основе среды PHP Slim, которая использует JSON Web Tokens (JWT) для аутентификации и авторизации доступа.

Чтобы использовать API, клиент должен сначала аутентифицировать себя, отправив свои учетные данныена специальный маршрут /auth/token, который, если он верен, возвращает токен с цифровой подписью, содержащий список разрешенных разрешений.Все последующие запросы к API требуют токен для аутентификации и авторизации.Это довольно стандартная штука и работает хорошо.

Но теперь я хочу разделить службу /auth/token на ее собственный микро-сервис, чтобы в будущем я мог повторно использовать ее с другими API.

Проблема в том, как API теперь будут аутентифицировать JWT, поскольку у них нет доступа к секрету, который использовался для его генерации?

Я использую Firebase\JWT\JWT для генерации токена, который будетперешел на новый сервис авторизации.И я использую промежуточное программное обеспечение tuupola/slim-jwt-auth для аутентификации полученного токена на каждом API.

Поскольку каждый API и новая служба аутентификации будут работать на одном и том же хосте, я мог бы поделиться секретом между ними, но это похоже наплохая практика.Есть ли лучший способ?

Ответы [ 2 ]

1 голос
/ 28 марта 2019

Криптографические алгоритмы, которые можно использовать для генерации кода аутентификации сообщения (MAC) или цифровой подписи, перечислены в RFC 7518 .

Во всем списке алгоритмов единственное, что «требуется» для реализации совместимой реализацией, - это HMAC с использованием SHA256 (HS256). HS256 требует секретного секрета для подписи токена, а также для проверки токена. Если вы используете HS256, в идеале вы не должны делиться секретом между всеми серверами. Вместо этого логика подписи и проверки tge останется на «сервере авторизации» (терминология OAuth2). Отдельные «серверы ресурсов» (опять же терминология OAuth2) будут вызывать службу на сервере авторизации для проверки токена. Однако может быть нецелесообразно вызывать API проверки токена сервера авторизации для каждого вызова API. Поэтому для серверов ресурсов может быть хорошей идеей кэшировать JWT и просто сравнивать JWT во входящих запросах с кэшированным списком JWT. Если входящий JWT отсутствует в кэше, то только тогда будут активированы функции проверки сервера авторизации. Это гарантирует, что секретный ключ подписи не нужно совместно использовать, и функция проверки удаленного сервера авторизации также не вызывается для каждого вызова API.

Два других рекомендованных алгоритма в RFC - это «RSASSA-PKCS1-v1_5 с использованием SHA-256» и «ECDSA с использованием P-256 и SHA-256» (ES256), где более поздний (ECDSA) также может быть сделано "обязательным" в будущем.

Если вы используете ES256, вы сохраните закрытый ключ на сервере авторизации для подписи токенов и поделитесь открытым ключом tge на всех серверах ресурсов, чтобы каждый сервер ресурсов мог проверить подпись с помощью открытого ключа. Это определенно спасает серверы ресурсов от вызова сервера авторизации для проверки за счет увеличения вычислений и без необходимости делиться секретом с каждым сервером ресурсов.

1 голос
/ 28 марта 2019

Лучше подписывать JWT, используя закрытый / открытый ключ (алгоритм RSA или ECDSA) вместо секретного (алгоритм HMAC).В этом случае ваша служба аутентификации подписывает JWT с закрытым ключом, а другие API проверяют JWT с открытым ключом, хорошо ... тогда вам все равно нужно распространить открытый ключ на ваши API, но у вас есть варианты.

В зависимости от вашей архитектуры вы можете посмотреть:

Шаблон API-шлюза

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

При таком подходе вам потребуется API-шлюз, вы можете посмотреть на: express-gateway, kong + jwt plugin , tyk и т. Д., Также есть гораздо больше преимуществ от шлюза API, а не просто проверка токена JWT, например, управление трафиком,аналитика, ведение журналов, преобразование запросов и ответов и т. д.

Управление секретами

Вместо или в дополнение к API Gateway вы можете взглянуть на централизованные системы управления секретами,как Хаси Хранилище .Зависит от размера проекта / команды, это может быть излишним для вашего проекта.

...