LINUX.ORG.RU

REST - ограничение доступа к публичному API

 , , , ,


2

1

День добрый.

Занесло меня на разработку серверной части достаточно крупного REST сервиса. Проект на Spring + Hibernate + Swagger. С социальным логином через Google и Facebook уже яснее. Но еще предполагается, что некоторая часть методов API будет доступна третьим лицам возможно с собственными клиентскими приложениями по подпискам или вроде того. То есть встал серьезный технический вопрос как это сделать. Кто-нибудь сталкивался с подобной задачей?

Сейчас рассматриваются варианты: через HTTP Basic аутентификацию , сертификаты и собственная реализация пересылки ключа через header или cookie. Первый вроде как подходит, там вообще обязательно использовать пару логин плюс пароль или можно свое что-то слать? Использование сертификатов показалось чересчур усложненным.

Еще вопрос: если генерировать ключ на подписчика, то какой алгоритм использовать? Какой-нибудь хэш? Или прокатит и случайный UUID?

★★★

то какой алгоритм использовать? Какой-нибудь хэш? Или прокатит и случайный UUID?

смотря что, если там приложение то выдать токен c hmac есесно предусмотреть возможность отзыва токена, нескольки токенов на один аккаунт

Deleted ()
Ответ на: комментарий от tailgunner

Это получается у нас есть какой-то сертефикат, мы отдаем подписчику дочерний сертификат и проверем когда он стучится? Рас сматривал этот вариант, но непонятно как это будет работать с веб-клиентами. У нас есть js-клиент, Android и iOS. Дальше - больше.

spoilt ★★★ ()

Все варианты нормальные. На мой взгляд HTTPS в современном мире использовать обязательно, поэтому клиентская аутентификация самый логичный вариант. Но его может быть сложно использовать с точки зрения программиста. Поэтому HTTP Basic аутентификация второй по предпочтительности вариант. Это HTTP стандарт, зачем изобретать что-то своё?

От самородной криптографии лучше отказаться. Нормально всё равно не напишете, если у вас там Брюс Шнайер в консультантах не ходит.

Legioner ★★★★★ ()
Ответ на: комментарий от spoilt

Это получается у нас есть какой-то сертефикат, мы отдаем подписчику дочерний сертификат и проверем когда он стучится?

Подписчик генерирует пару ключей и сообщает вам открытый ключ. Вы генерируете сертификат с этим открытым ключом, подписываете его своим закрытым ключом и передаёте его (сертификат) подписчику.

Рассматривал этот вариант, но непонятно как это будет работать с веб-клиентами. У нас есть js-клиент, Android и iOS. Дальше - больше

В JS — никак. Если вашим сервисом пользуются браузеры, а не другие программы, тогда не подходит. Android и iOS — без проблем.

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

Legioner ★★★★★ ()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от Deleted

Пробовал читать про hmac, там писалось, что хэшируется все сообщение. Это правда? Про несколько токенов на аккаунт думаю и так будет.

spoilt ★★★ ()
Ответ на: комментарий от spoilt

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

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

другой вариант - голый рандом, но тогда его сразу придется держать в базе

зы. и в спринге еть готовая реализация для токенов

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)

Spring security (раз уж все равно Spring у вас), нэ?

shty ★★★★★ ()

Если предубеждений фантомов на https нет, то можно использовать обычные персональные сертификаты, поддерживаемые всеми браузерами.

Наконец, можно по туннелям через http

anonymous ()
Ответ на: комментарий от Legioner

HTTPS в любом случае будет. Это не смешно использовать голый HTTP в 2016 году.

spoilt ★★★ ()
Ответ на: комментарий от Legioner

В JS — никак. Если вашим сервисом пользуются браузеры, а не другие программы, тогда не подходит. Android и iOS — без проблем.

Тогда будем смотреть в сторону HTTP Basic.

Но какой толк тогда во всей этой аутентификации, если ваши ключи будут уходить пользователю в браузер?

Так по этим ключам будет проверятся только может ли конкретное приложение иметь доступ к API, авторизация и аутентификация пользователей отдана на сьедение Google Identify Toolkit.

AJAX на другие серверы нельзя делать.

CORS же еще будет настраивается. С ним будет отдельная песня. Вообще картина интересная - хотят проект уже 1 марта, а до конца еще не все ясно зачем оно такое.

spoilt ★★★ ()
Ответ на: комментарий от Deleted

Прикольная штука.

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

Не проще ли какой-то короткоживующий кукис отдать в ответе?

зы. и в спринге еть готовая реализация для токенов

Как называется-то? Я пока в спринге только месяц разбираюсь.

spoilt ★★★ ()
Ответ на: комментарий от spoilt

Не проще ли какой-то короткоживующий кукис отдать в ответе?

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

Deleted ()

Вообще, неужели в java-экосистеме нет нормальных стандартных решений вроде asp.net identity и owin, которые подключаются в две строчки и просто работают? Какая HTTP Basic в 2016м году, вы что? Или тем более, самому пилить...

lovesan ★★ ()

Какой-нибудь хэш? Или прокатит и случайный UUID?

На этой вашей жабе принято механизм сессий самому велосипедить?

anon1984 ()
Ответ на: комментарий от Legioner

В JS — никак. Если вашим сервисом пользуются браузеры, а не другие программы, тогда не подходит.

Ага, прям так сложно выяснить на фронтенд веб-сервере, что это за клиентский сертификат, и установить заголовок для передачи бекенду.

anon1984 ()
Ответ на: комментарий от spoilt

Да при чем тут сторонние приложения. Тебе от OAuth2 нужно только следующее: открываешь endpoint, который принимает

{ grant_type: "password", username: "USER", password: "PASSWORD" }
и выдает
{ access_token: "TOKEN", expires_in: SECONDS }
или
{ error: "invalid_grant" }
Дальше, клиент берет токен и каждый раз при защищенном вызове API, передает http-заголовок
Authorization: Bearer $TOKEN
Дальше, когда ты токен при вызове получаешь, расшифровываешь его, берешь из него id/имя юзера и когда он истекает. Если истек - говоришь ошибка и возвращаешь 401 какой-нибудь, если ок - работаешь с пользователем дальше.

В Asp.Net это все делает за тебя фреймворк OWIN с подключенным модулем OAuth и Asp.Net Identity 2.0. Никакого велосипедизма, никакого ручного хеширования паролей и прочего - только DAL свой подставляй для нужд фреймворка и все, остальное делается за тебя. Я не верю что в Java нет аналогов.

Просто как полено. Еще раз, какой нафиг Http Basic? Какие велосипеды? Все давно написано.

lovesan ★★ ()
Ответ на: комментарий от Deleted

Почитал еще раз твое сообщение с разьяснением. Получается если добавить еще заранее известный сторонам секретный ключ (какое-то слово или UUID), то выйдет неплохое решение моей проблемы. Если веб-девелоперы осилят, то будет круто.

spoilt ★★★ ()
Ответ на: комментарий от lovesan

Потому что ищется способ обноса API защитой именно от сторонних приложений, о чем и говорилось в ТС. Пользователями будет рулить Google Identify Toolkit. Там oAuth2 и барышни.

spoilt ★★★ ()
Ответ на: комментарий от spoilt

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

lovesan ★★ ()
Ответ на: комментарий от lovesan

Какая разница какой у него клиент.

Большая. Ибо данные со всего этого будут продаваться. Есть методы, которые не требуют каких-либо привелегий, но данные не должны утекать. Заплатил деньгу - получай доступ. Можешь даже не логинится.

Если клиент важен, так тем более OAuth2, в полном виде - как раз и подходит. В таком случае добавляется шаг выдачи токена клиента.

Тобишь пользователь, условно заплатил деньгу, и может выдать токен какому-то своему клиенту. Или возможно централизовано?

spoilt ★★★ ()
Ответ на: комментарий от anon1984

Как ты скомпрометируешь генератор токенов, если это будет UUID.random().toString() и плюс еще хэшироваться будет? Гипотетически.

spoilt ★★★ ()
Ответ на: комментарий от Legioner

От самородной криптографии лучше отказаться. Нормально всё равно не напишете, если у вас там Брюс Шнайер в консультантах не ходит.

Можно мне услышать хоть какие-то внятны основании для этого утверждения?

anonymous ()
Ответ на: комментарий от anonymous

Криптография это очень сложно. При этом кажется, что это очень просто и любой ламер, прочитавший пару статей из википедии, радостно бросается вперёд на амбразуры, лепить свои протоколы. И, что самое страшное, эти протоколы вроде как работают, вроде как что-то там шифруется, подписывается. Если у ламера-программиста всё будет глючить и падать, то у ламера-криптографа всё будет тип-топ, пока его не разломают.

Legioner ★★★★★ ()
Ответ на: комментарий от anon1984

Который будет генерироваться через похожую колоду и будет для каждого приложения свой.

spoilt ★★★ ()
Ответ на: комментарий от spoilt

добавить еще заранее известный сторонам секретный ключ

это какбы и есть хеш пароля + название приложения

Deleted ()

Использование сертификатов показалось чересчур усложненным.

С одной стороны — да. С другой стороны, в принципе все адекватные пользователи уже приучены: давно уже ходят на те же госзаукпки по клиентским сертификатам, с отечественной между прочим криптографией.

Если сервис премиальный и пользователей будет относительно немного, то аутентификацию можно производить и по *квалифицированным* сертификатам. Минимум телодвижений с твоей стороны.

Есть только два больших вопроса:

1. На коленке такие вещи не делаются. Нужна железка.

2. Если ты захочешь предоставлять пользователям шифровальные услуги (читай захочешь юридического признания их операций и/или возникнут вопросы ПДН), то тебе придётся получать лицензию ФСБ и использовать отечественную криптографию. В противном случае тебя очень быстро (и без вазелина) нагнёт Роскомнадзор.

Macil ★★★★★ ()
Ответ на: комментарий от maloi

Потому что нет в AJAX такого API. Только если вся страница будет грузиться с клиентским сертификатом. Но т.к. UI у всех браузеров при работе с клиентскими сертификатами ужасный (банально logout нельзя сделать), этот вариант не подходит.

Legioner ★★★★★ ()
Ответ на: комментарий от Legioner

Только если вся страница будет грузиться с клиентским сертификатом.

Нет смысла делать как-то иначе

Но т.к. UI у всех браузеров при работе с клиентскими сертификатами ужасный (банально logout нельзя сделать), этот вариант не подходит.

Куча сервисов так делают, с чего ты взял что топикстартеру это не подойдёт? Только из-за твоих болей от плохого ux твоего браузера?

maloi ★★★★★ ()
Ответ на: комментарий от Macil

Если сервис премиальный и пользователей будет относительно немного.

Пользователей ожидается дохрена.

давно уже ходят на те же госзаукпки по клиентским сертификатам

Несовсем. Скорее это микросоцсеть.

Нужна железка.

Что еще за железка?

Второй пункт вообще не об этом. Сервис пишется для забугорных товарищей и никаких шифровальных услуг. И пишут в основном в Украине.

spoilt ★★★ ()
Ответ на: комментарий от lovesan

Ты не отличаешь авторизацию приложения-клиента и самого пользователя системы?

spoilt ★★★ ()
Ответ на: комментарий от Legioner

Планируются встраиваемые на левые сайты виджеты. Правда еще пока решают будет это голый JS (вопрос как хранить ключи?) или PHP. Сейчас еще подымаю oAuth демку спринга, для полноты картины.

spoilt ★★★ ()
Ответ на: комментарий от spoilt

Автор, тебе уже несколько человек написал, что есть Spring Security. В интернете полно примеров как добавить секьюрности к рест-сервису с помощью этого модуля на основе авторизации юзеров.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.