Нужны советы по обеспечению безопасности частного REST API, написанного на python-flask
В настоящее время я пишу API отдыха в Python с микросхемой Flask. Это частный API, и он имеет дело с пользовательскими данными. Я планирую использовать этот API для создания веб-приложений и приложений для Android.
Сейчас я использую дайджест-аутентификацию для защиты личных данных пользователя. Например, если вы хотите опубликовать данные на моем сервисе с помощью пользователя bob, вы отправляете запрос на myapi/story/create и предоставляете учетные данные bob с помощью шаблона дайджеста.
Я знаю, что это не очень хорошее решение, потому что:
-Дайджест аутентификации небезопасен
-Клиент не аутентифицирован (Как защитить запросы, не связанные с текущим пользователем, например, создать нового пользователя?)
Я много читал об oAuth, но трехсторонняя аутентификация кажется излишней, потому что я не планирую открывать свой API для третьих лиц.
Двухсторонний oAuth не подходит, потому что он обеспечивает аутентификацию только для клиентов, а не для пользователей.
Другая проблема с oAuth заключается в том, что я не нашел исчерпывающего руководства по его реализации на Python. Я нашел библиотеку python-oauth2, но я не понимаю пример сервера и не могу найти дополнительную документацию. Кроме того, похоже, что многие аспекты oAuth не рассматриваются в этом примере.
Итак, мои вопросы:
- Существует ли альтернативная схема (не oAuth) для аутентификации клиента и пользователя с разумным уровнем безопасности?
- Если oAuth - лучшее решение:
- Как пропустить процесс авторизации (поскольку пользователям не нужно будет авторизовать сторонних клиентов)?
- Есть ли подробная документация для python-oauth2 или для любой другой библиотеки Python?
Любая помощь или совет будут оценены.
3 ответа
Простой ответ - предоставить ваш API только через HTTPS, а затем использовать обычную проверку подлинности HTTP. Я не думаю, что есть какая-то причина беспокоиться о дайджесте. Обычная аутентификация небезопасна, но отправляется с каждым запросом, поэтому вам не нужно беспокоиться о том, что ваша аутентификация устарела или что-то в этом роде. Туннелируя его по HTTPS, вы получаете безопасное соединение.
Если вы хотите аутентифицировать клиента, вы можете использовать SSL-сертификаты клиента. Тем не менее, в целом довольно сложно действительно заблокировать клиент от злонамеренных пользователей, поэтому я хотел бы рассмотреть возможность сделать функции регистрации открытыми и защитить себя от DOS и т. Д. С помощью внеполосной проверки учетной записи.
Вы уже рассматривали возможность использования базовой аутентификации?
Я еще не использовал упомянутую вами платформу, но я использовал базовую аутентификацию для защиты некоторых 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
Если вы заинтересованы в базовой аутентификации, вот быстрый атрибут, который вы можете использовать для украшения ваших обработчиков 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
Это может быть немного поздно, но это мне очень помогло. В основном объясняет, как безопасность работает в Amazon (они не поддерживают oauth)
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/