1
0
mirror of https://github.com/twirl/The-API-Book.git synced 2025-05-31 22:09:37 +02:00

AA translated

This commit is contained in:
Sergey Konstantinov 2023-04-18 20:15:43 +03:00
parent a7becf1b80
commit 21499a4d40
2 changed files with 49 additions and 2 deletions

View File

@ -1 +1,25 @@
### Authenticating Partners and Authorizing API Calls
### [Authenticating Partners and Authorizing API Calls][api-patterns-aa]
Before we proceed further to discussing technical matters, we feel obliged to make an overview of the problems of authorizing API calls and authenticating clients that make it. Based on the very same main principle (“an API serves as a multiplier to both your opportunities and mistakes”), organizing authorization & authentication (AA) is one of the most important problems that any API vendor faces, especially if we talk about public APIs. So it's rather surprising that there is basically no standard approach to it: every big vendor develops its own interface to solve AA issues, and those interfaces are often quite archaic.
If we put aside implementation details (regarding which we once more strongly recommend not inviting a bicycle and using standard techniques and security protocols), there are basically two approaches to authorizing an API call:
* introduce a special “robot” type of account into the system, and carry on the operations on behalf of the robot account;
* authorize the caller system (backend or client application) as a single entity (usually API keys, signatures, or certificates are used for the purpose of authenticating such calls).
The difference between the two approaches is the access granularity:
* if an API client is making requests as a regular user of the system, then it can conduct only the operations allowed to a specific user which in most cases implies it might have access only to a partial dataset within the API endpoint;
* if the caller system is authorized, it implies that it has full access to the endpoint and might supply any parameters (i.e., has access to the full dataset exposed through the endpoint).
Therefore, the first approach is more granular (the robot might be a “virtual employee” and have access only to some limited dataset) and is a natural choice for those APIs that are supplemental to the existing service for end users (and thus might reuse the existing AA solutions). The disadvantages of the approach are:
1. The necessity to develop the process of safely fetching authorization tokens for the robot user (for example, via making a real user generate tokens somewhere in the web UI) as regular login-password authentication (especially multi-factored) is poorly applicable to API clients.
2. The necessity of to make exceptions for robot users in almost every security protocol:
* robots might make much more requests per second than real users, and might do several queries in parallel (possibly from several different IP addresses located in different availability zones)
* robots won't set cookies and can't solve captcha
* robots should not be logged out or have their token invalidated “just in case” (as it means the partner's business processes will suffer), so it is usually necessary to invent specific long-living tokens for robots and/or token renew procedure.
3. Finally, you will face big problems if it happens you *need* to allow robots to conduct operations on behalf of other users (as you will have to either expose this functionality to all users or, conversely, hide its existence from them).
If the API is not about providing additional access to some service for end users, it's usually much easier to opt-in for the second approach and authorize clients with API keys. Per-endpoint granularity might be achieved in this case (i.e., allowing partners to regulate the set of permitted endpoints for a key); developing more granular access might be much more complex and rarely see realization.
Both approaches might be morphed into one another (if we allow robot users to conduct operations on behalf of any other users, it's effectively API key-based authorization; if we allow binding some limited dataset to API key, it effectively becomes a user account), and there are some hybrid systems in the wild (the request requires to be signed with both API key and user token).

View File

@ -1 +1,24 @@
### Аутентификация партнёров и авторизация вызовов API
### [Аутентификация партнёров и авторизация вызовов API][api-patterns-aa]
Прежде, чем мы перейдём к обсуждению технических проблем и их решений, мы не можем не остановиться на важном вопросе авторизации вызовов API и аутентификации осуществляющих вызов клиентов. Исходя из всё того же принципа мультипликатора («API умножает как возможности, так и проблемы») организация авторизации и аутентификации (AA) — одна из самых насущных проблем провайдера API, особенно публичного. Тем удивительнее тот факт, что в настоящий момент не существует стандартного подхода к ней — почти каждый крупный сервис разрабатывает какой-то свой интерфейс для решения этих задач, причём зачастую достаточно архаичный.
Если отвлечься от технических деталей имплементации (в отношении которых мы ещё раз настоятельно рекомендуем не изобретать велосипед и использовать стандартные подходы и протоколы безопасности), то, по большому счёту, есть два основных способа авторизовать выполнение некоторой операции через API:
* завести в системе специальный тип аккаунта «робот» и выполнять операции от имени робота;
* авторизовать вызывающую систему (бэкенд или клиентское приложение) как единое целое (обычно для аутентификации таких вызовов используются API-ключи, подписи или сертификаты).
Разница между двумя подходами заключается в гранулярности доступа:
* если клиент API выполняет запросы от имени пользователя системы, то его доступ к эндпойнту может быть ограничен каким-то конкретным набором данных, к которым имеет доступ пользователь;
* если же авторизуется вызывающая система, то обычно подразумевается, что она имеет полный доступ к эндпойнту, и может передавать любые параметр (т.е. имеет доступ к полному набору данных, предоставляемых через эндпойнт).
Первый подход, таким образом, является более гранулярным (робот может быть «виртуальным сотрудником» организации, то есть иметь доступ только к ограниченному набору данных) и вообще является естественным выбором для тех API, которые являются дополнением к существующему сервису для конечных пользователей (и, таким образом, иогут использовать уже существующие системы AA). Недостатками же этого подхода являются:
1. Необходимо организовать какой-то процесс безопасного получения токенов авторизации для пользователя-робота (например, через получение для него токенов реальным пользователем из веб-интерфейса), поскольку стандартная логин-парольная схема логина (тем более двухфакторная) слаба применима к клиенту API.
2. Необходимо сделать для пользователей-роботов исключения из почти всех систем безопасности:
* роботы выполняют намного больше запросов, чем обычные люди, и могут делать это в параллель (в том числе с разных IP-адресов, расположенных в разных дата-центрах);
* роботы не принимают куки и не могут решить капчу;
* робота нельзя профилактически разлогинить и/или инвалидировать его токен (это чревато простоем бизнеса партнёра), поэтому для роботов часто приходится изобретать токены с большим временем жизни и/или процедуру «подновления» токена.
3. Наконец, вы столкнётесь с очень большими проблемами, если вам всё-таки понадобится дать роботу возможность выполнять операцию от имени другого пользователя (поскольку такую возможность придётся тогда либо выдать и обычным пользователям, либо каким-то образом скрыть её и разрешить только роботам).
Если же API не предоставляется как сервис для конечных пользователей, второй подход с авторизацией клиентов через API-ключи более прост в имплементации. Здесь можно добиться гранулярности уровня эндпойнта (т.е. партнёр может выставить для ключа набор эндпойнтов, которые можно с ним вызывать), но более гранулярные системы (когда ключу выставляются ещё и ограничения на уровне бизнес-сущностей) уже намного сложнее в разработке и применяются редко.
Обе схемы, в общем-то, можно свести друг к другу (если разрешить роботным пользователям выполнять операции от имени любых других пользователей, мы фактически получим авторизацию по ключу; если создать по API-ключу какой-то ограниченный сегмент данных в рамках которого выполняются запросы, то фактически мы получим систему аккаунтов пользователей), и иногда можно встретить гибридные схемы (когда запрос авторизуется и API-ключом, и токеном пользователя).