Ищете совет по защите частного REST API, написанного в python-колбе
В настоящее время я пишу API для отдыха в python с микрофлокой Flask. Это частный API, и он имеет дело с пользовательскими данными. Я планирую использовать этот API для создания веб-приложения и приложения для Android.
В настоящее время я использую digest auth для защиты частных пользовательских данных. Например, если вы хотите публиковать данные на моем сервисе с помощью пользователя bob, вы делаете запрос на почту в myapi/story/create и предоставляете учетные данные bob с помощью шаблона дайджеста.
Я знаю, что это нехорошее решение, потому что:
-Digest auth не безопасно
-Клиент не аутентифицирован (как защитить запросы, не связанные с текущим пользователем, например, создать нового пользователя?)
Я прочитал много статей о oAuth, но трехсторонняя аутентификация кажется излишней, потому что я не планирую открывать свой API для третьей стороны.
2-legged oAuth не подходит, поскольку он обеспечивает аутентификацию только для клиентов, а не для пользователей.
Другая проблема с oAuth заключается в том, что я не нашел исчерпывающего руководства по ее реализации в Python. Я нашел библиотеку python-oauth2, но я не понимаю пример сервера, и я не могу найти дополнительную документацию. Плюс, похоже, что многие аспекты oAuth не рассматриваются в этом примере.
Итак, мои вопросы:
- Существует ли альтернативная схема (а не oAuth) для аутентификации как клиента, так и пользователя с разумным уровнем безопасности?
- Если oAuth - лучшее решение:
- Как пропустить процесс авторизации (поскольку пользователям не нужно разрешать сторонние клиенты)?
- Есть ли подробная документация для python-oauth2 или для любой другой библиотеки Python?
Любая помощь или совет будут оценены.
Ответы
Ответ 1
Простой ответ заключается в том, чтобы разоблачить ваш API только через HTTPS, а затем использовать HTTP Basic authentication. Я не думаю, что есть какая-то причина беспокоиться о Дайджесте. Обычная проверка подлинности небезопасна, но отправляется с каждым запросом, поэтому вам не нужно беспокоиться о том, что ваша аутентификация устарела или что-то еще. Путем туннелирования через HTTPS у вас есть безопасное соединение.
Если вы хотите аутентифицировать клиента, вы можете использовать сертификаты клиента SSL. Тем не менее, в целом довольно сложно блокировать клиента от вредоносных пользователей, поэтому я хотел бы рассмотреть возможность открытого доступа к функциям регистрации и защитить себя от DOS и т.д. Посредством проверки внеполосной учетной записи.
Ответ 2
Вы уже считали, что используете базовую аутентификацию?
Я еще не использовал фреймворк, который вы упомянули, но я использовал базовый auth для защиты некоторых URL-адресов в приложении на основе web.py и работал нормально.
В принципе, вы можете использовать токен в base64, который на самом деле является стандартным http-хейдером.
Возможно, этот пример может помочь вам:
class Login:
def GET(self):
auth = web.ctx.env.get('HTTP_AUTHORIZATION')
authreq = False
if auth is None:
authreq = True
else:
auth = re.sub('^Basic ','',auth)
username,password = base64.decodestring(auth).split(':')
if (username,password) in settings.allowed:
raise web.seeother('/eai')
else:
authreq = True
if authreq:
web.header('WWW-Authenticate','Basic realm="Auth example"')
web.ctx.status = '401 Unauthorized'
return
Ответ 3
Если вы заинтересованы в базовой аутентификации, вот быстрый атрибут, который вы можете использовать для украшения ваших обработчиков http://www.varunpant.com/posts/basic-authentication-in-web-py-via-attribute. Этот пример написан в основном в контексте web.py, но я думаю, его можно легко настроить.
def check_auth(username, password):
return username == 'username' and password == 'password'
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = web.ctx.env['HTTP_AUTHORIZATION'] if 'HTTP_AUTHORIZATION' in web.ctx.env else None
if auth:
auth = re.sub('^Basic ', '', auth)
username, password = base64.decodestring(auth).split(':')
if not auth or not check_auth(username, password):
web.header('WWW-Authenticate', 'Basic realm="admin"')
web.ctx.status = '401 Unauthorized'
return
return f(*args, **kwargs)
return decorated
Ответ 4
Это может быть немного поздно, но это очень помогло мне. В основном объясняется, как безопасность работает на амазонке (они не поддерживают oauth)
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/