Как стать автором
Обновить

Комментарии 16

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

Если нужно сократить количество машин, которые нужно особо внимательно охранять, нужно получить возможность проверять валидность авторизационного токена без полного знания секрета. Это можно сделать двумя способами:
1. Всегда ходить в сервис, который выдавал токен, чтобы он его и валидировал. По сути — oauth.
2. Подписывать токен ассиметричной криптографией, например RSA. Ключ при этом нужно выбрать достаточно коротким (я бы сказал, 1024 бит будет достаточно), и ротировать его регулярно. На каждом клиенте при этом будет только публичный ключ, приватный же только внутри сервиса, который токены генерирует. Эллиптические кривые тоже можно использовать, валидация будет работать даже быстрее, но подпись генерируется значительно дольше. Чтобы проверить скорость генерации/проверки подписи разными шифрами можете использовать утилиту openssl speed прямо на своём сервере. На моём самом дешёвом дроплете от DO получились вот такие цифры:
~$ openssl speed ecdsap160 rsa1024
Doing 1024 bit private rsa's for 10s: 43546 1024 bit private RSA's in 9.98s
Doing 1024 bit public rsa's for 10s: 626236 1024 bit public RSA's in 9.99s
Doing 160 bit sign ecdsa's for 10s: 123664 160 bit ECDSA signs in 9.99s
Doing 160 bit verify ecdsa's for 10s: 33559 160 bit ECDSA verify in 9.98s
OpenSSL 1.0.1f 6 Jan 2014
built on: Thu Mar 19 15:12:02 UTC 2015
options:bn(64,64) rc4(16x,int) des(idx,cisc,16,int) aes(partial) blowfish(idx)
compiler: cc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
                  sign    verify    sign/s verify/s
rsa 1024 bits 0.000229s 0.000016s   4363.3  62686.3
                              sign    verify    sign/s verify/s
 160 bit ecdsa (secp160r1)   0.0001s   0.0003s  12378.8   3362.6


Оба метода идеально горизонтально масштабируются (потому что шарят только ключи), позволяют сделать 2-уровневую защиту. Заодно сервис аутентификации может и куку пользователя менять на токен, что добавит защиты.
Насчет асиметричного шифрования пожалуй соглашусь. А вот с утверждением "в этой схеме при компрометации любого компонента появляется возможность генерировать токены в любом количестве" смею поспорить. Для генерации токенов нужно скомпроментировать один из сервисов имеющих доступ к кэшу redis. Т.е. или auth или nginx.
nginx у вас живёт в отдельном контейнере от приложения, исполняющего полезную работу? Если да, то как защищено взаимодействие nginx и приложения, и почему в него можно сходить только из nginx?

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

наоборот (даже по тесту видно)
Да, это я что-то неправильно запомнил :(
Автор, исправьте ошибку в первом слове заголовка статьи… пожалуйста.
собственно во всей статье, 6 раз
В заголовке особенно «режет глаз».
Он может содержать в себе все что угодно, в принципе это может быть и просто client_id и какая-то другая информация о пользователе, но это не очень хорошая идея

Немоглибы пояснить почему?
как я понимяю JWT это был-бы иделаьный варинат для микросервисов… А дополнительная валидация в nginx какрыз костыль…
Идея в том, что аутентификация и проверка токена это не есть непосредственная задача микросервиса. Пускай этим занимается промежуточный сервис. Кроме того конкретному микросервису как правило нужно очень мало информации о клиенте, ID в принципе для большинства задач хватит, но не хочется это все в токене хранить, не всегда это нужно пользователю знать. и на каждый чих пых дергать auth сервис тоже не здорово.
Идея в том, что аутентификация и проверка токена это не есть непосредственная задача микросервиса.

Ну это понятно, но какой-то boilerplate есть всегда темболее что в данном случае это решает какая-нибудь либа.
Утрировано проблема лишней строчки кода помоему не страшно…
Далее не всем сервисам нужда аутентикация/авторизация в принципе… но тем которым нужна нужна скорее всего достаточно псецифически (именно авторизация). Так что куда-то делегироваТь эту задачу мене кажется далеко не суперской идеей.
Кроме того конкретному микросервису как правило нужно очень мало информации о клиенте, ID в принципе для большинства задач хватит, но не хочется это все в токене хранить, не всегда это нужно пользователю знать

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

Может я конечно не совсем верно понял JWT, но помеомеу о идеален именно для это-го

Как уже писали выше, стандартное решение для микросервисной архитектуры — OAuth2. Преимущества — изолированный сервис аутентификации, стандарт, наличие всяких интересных плюшек помимо обычной аутентификации по токену.

Что касается авторизации — я не уверен, что пихать её в nginx — хорошая идея. Логика авторизации часто зависит от конкретного приложения. Как вариант, можно настроить nginx, чтобы он сам валидировал токен и добавлял в заголовки юзернейм, а логику авторизации все-таки оставить приложению.
У OAuth2 один минус: нужно каждый раз ходить в сервис авторизации, может стать боллтнеком, ну и latency это добавляет. Но если оба пункта не сильно важны в текущий момент, то это действительно неплохой выбор, пусть и несколько переусложнённый.

Если всё же интересны локально проверяемые токены, то рекомендую почитать про Google Macaroons.
Токены можно кешировать локально на небольшой интервал времени, это снимает проблему нагрузки, а заодно и latency, если обращаются одни и те же юзеры. Проблема с локально проверяемыми токенами в том, что их нельзя оперативно отозвать, а также в вычислительной сложности или безопасности — смотря как они подписаны.

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