А какой у нас сейчас state of the art для авторизации на связанных сайтах. Есть один главный сайт foo.bar.com, есть N сервисов (только web sockets) на которые юзверь так же может посылаться. На foo.bar.com есть авторизация через oauth, так же проверяются права на то, какие сервисы есть права и где они живут и туда посылается юзверь. Вопрос в том, как сделать так чтобы сервис мог бы дешево проверять что юзверь это действительно нормальный юзверь и имеет доступ, не реализуя логику авторизации на двух узлах
2017-05-10 12:07:30

Участники:
@qnikst - 13, @alar - 9, @gbdj - 2, @segfault - 2, @agr - 2, @Renha - 1

@agr
Правильно я понимаю, что если он авторизовался на foo.bar.com, то всегда можно этот факт сохранить либо на foo.bar.com, либо где-то ещё, а потом с других точек можно пробрасывать логику сравнения туда, где хранится факт авторизации?
#2870998/1 2017-05-10 12:10:40
@qnikst
сервисы и foo.bar.com могут общаться между собой по приватной сети. Но если этого можно как-то избежать, то было бы круче.
#2870998/2 → /1 2017-05-10 12:11:24
@qnikst
сохранять тоже можно.
#2870998/3 → /2 2017-05-10 12:11:39
@Renha
Это получаются токены, да?
#2870998/4 → /1 2017-05-10 12:13:08
@agr
да
#2870998/5 → /4 2017-05-10 13:09:21
@segfault
oauth2 же
#2870998/6 2017-05-10 13:16:18
@segfault
Не дочитал. Не реализуя на двух узлах - это фантастика имх.
#2870998/7 → /6 2017-05-10 13:17:18
@qnikst
ну сервер может знать публичный ключ сервиса и шифровать какое-то сообщение, которое вместе с токеном клиент отдает для авторизации, итого авторизация есть, но возможно дешевле чем oauth
#2870998/8 → /7 2017-05-10 13:34:15
@alar
удваиваю OAuth. Я его на днях ковырял.
#2870998/9 → /6 2017-05-11 07:42:11
@qnikst
oauth и так на главном, иметь его на каждом узле как-то печально
#2870998/10 → /9 2017-05-11 07:42:50
@alar
Так оно же из двух кусков состоит: сервер и relying party.
#2870998/11 → /10 2017-05-11 07:43:33
@qnikst
мне ж на каждом из сервисов придется медленную авторизацию с беганием к провайдеру делать?
#2870998/12 → /11 2017-05-11 07:45:17
@alar
к серверу OAuth, да. Чтобы убедиться, что то, что тебе клиент впарил в качестве токена - действительно выдал сервер. Вот лично у меня всё крутится вне открытых интернетов, и провайдеру я доверяю, и можно было бы обойтись двумя кэшами секретных токенов: у меня и у провайдера, и схемой их регенерации (а её для OAuth2 всё равно надо городить), но это получится свой велосипед, некруто.
#2870998/13 → /12 2017-05-11 07:48:40
@qnikst
мне очень не хочется делать вторую авторизацию видимой для пользователя и жрущую время идеально это должно быть невидимо.
#2870998/14 → /13 2017-05-11 07:49:58
@alar
у меня по замыслу она тоже должна быть невидимой: пользователь ко мне приходит по ссылке с провайдера сразу с токеном. Правда эти токены надо как-то заранее сгенерить, этот момент на схеме OAuth2 условно не показан, да.
#2870998/15 → /14 2017-05-11 07:53:14
@qnikst
я не понимаю.. мне нужно чтобы когда его пошлют на сервис пользователь не ходил к провайдеру ещё раз, это возможно?
#2870998/16 → /15 2017-05-11 08:01:19
@alar
Для этого его должны на сервис послать уже с каким-то токеном доступа, так?
#2870998/17 → /16 2017-05-11 08:02:14
@qnikst
видимо
#2870998/18 → /17 2017-05-11 08:28:03
@alar
а этот токен он откуда получит? В классическом OAuth2 его посылают за токеном к провайдеру редиректом. В моём случае юзер на мой сервис придёт по ссылке с провайдера, и предполагается, что провайдер откуда-то заранее узнает токен и предусмотрительно ему подложит в ссылку.
#2870998/19 → /18 2017-05-11 08:31:45
@qnikst
смотри, у меня в /0 вопрос, как бы сделать это без редиректа к провайдеру; мне в ответ предлагают сделать редирект к провайдеру, мне это не очень нравится. Я вижу что то, что я хочу в принципе возможно сделать, но поидее оно обрастет кучей костылей для того, чтобы быть полноценным решением, чего бы мне не хотелось :/
#2870998/20 → /19 2017-05-11 08:47:06
@alar
Я из тебя пытаюсь вытянуть, как клиент получит токен, который он в классическом случае добывает через редирект к провайдеру. В твоём юзкейсе. > поидее оно обрастет кучей костылей для того, чтобы быть полноценным решением В моём юзкейсе OAuth2, но он уже обрастает костылями. Потому что иначе неудобно. Один костыль - наколенная схема регенерации токенов растёт прямо из самого OAuth2.
#2870998/21 → /20 2017-05-11 08:51:25
@qnikst
в том, что я вижу, мы можем на сервере сгенерировать блоб, в котором публичным ключем клиента зашифрованы: информация для авторизации, timestamp, token + token, клиент шлёт этот блоб при создании соденинения и по нему происходит аутенфикация, дальше для этой сессии достаточно только токена. В этой схеме не хватает механизма обновления токенов разве что.
#2870998/22 → /21 2017-05-11 09:01:31
@alar
в этой схеме не раскрыто, как клиент получает "блоб", сгенерированный на сервере
#2870998/23 → /22 2017-05-11 09:02:45
@qnikst
клиент делает коннект к foo.bar.com авторизуется через oauth, делает запрос на сервис, ему в ответ приходят адрес и блоб
#2870998/24 → /23 2017-05-11 10:06:00
@alar
умный клиент сам раскрывает блоб и дальше спокойно работает?
#2870998/25 → /24 2017-05-11 10:06:59
@qnikst
не раскрывает, а тупо пересылает сервису когда конеектится
#2870998/26 → /25 2017-05-11 10:07:53
@gbdj
Пользуясь случаем сначала хочу заметить что oauth2 это просто хипстерская реимплементация Kerberos-а =) Теперь по сути. Про термины. SSO состоит из логинилки и верификатора. Логинилка содержит сколь угодно сложную логику хоть с рассылкой sms хоть с oauth (как у тебя) и делает аутентификацию пользователя (выясняет что он тот за кого себя выдает) а затем иногда может делать авторизацию (выяснят что тому разрешено) если конечно логинилка имеет необходимый доступ до разных систем привилегий всего зоопарка приложений. Но часто логинилка делает только аутентификацию и оставляет авторизацию конкретному приложению. При успешной аутентификации логинилка возвращает клиенту нечто (назовем его cookie), что необходимо затем скармливать с каждым запросом к любому из сервисов. Верификатор же, должен проверять валидность cookie в каждом запросе. Дальше посмотрим на варианты верификатора: Лично предпочитаю при любом дальнейшем раскладе выносить верификатор на http фронтенд а ля nginx при помощи модуля ngx_http_auth_request_module http://nginx.org/en/docs/http/ngx_http_auth_request_module.html nginx делает авторизационный подзапрос который к случае успеха вернут 200 и пару дополнительных http заголовков с именем пользователя и возможно списком привилегий для веб приложений. В пределах минуты авторизационные ответы можно закэшировать штатными средствами и подразгрузить верификатор. Главное что мы получаем единую логику верификатора для всего зоопарка. 1. В качестве cookie используем 32 байта рандома, но не пытаемся при этом изобрести свой. В этом случае для верификации нам нужно держать таблицу соответствия рандомных cookie и пользователей, а значит шарить состояние с логинилкой, а так же с другими фронтенд серверами если они есть. Плюс один, не нужно шарить состояние с веб приложениями. 2. В качестве cookie используем plaintext набор параметров содержащих timestamp протухания и HMAC всей исходной строки ( exp=1234567890&data=pupkin&digest=HMAC ) Схема подробно разобрана тут : https://pdos.csail.mit.edu/papers/webauth:sec10.pdf Главное использовать не hash а именно HMAC и не сходить с тропинки. =) Логинилка и сервера фронтендов шарят между собой только секрет используемый для генерации HMAC. Динамическое расшареное состояние отсутствует вообще. То что cookie протух можно проверить до его полной верификации ибо plaintext. Минус что нельзя пихать чувствительную информацию о пользователе ибо подпись есть, а криптации нет. Но во много схема оптимальна. 3. Используем public key криптографию для cookie. Логинилка подписывает своим приватным ключем, а затем криптует публичным ключем верификаторов. Если фронтенд серверов больше одного, то нужно шарить среди них приватный ключ верификатора. Однако отсутствует расшаренное состояние с логинилкой. Компрометация приватного ключа верификатора позволяет прочитать авторизационную информацию, но не компрометирует саму авторизацию. Очень легко тут накосячить в реализации, от существующих в дикой природе волосы встают дыбом. Вероятен смертный грех "изобретения своего криптографического протокола"
#2870998/27 2017-05-11 18:10:04
@qnikst
спасибо!
#2870998/28 → /27 2017-05-11 22:25:41
@gbdj
на здоровье =)
#2870998/29 → /28 2017-05-11 22:32:39