Как предоставить права клиенту, который не является пользователем в Django?
У меня есть приложение Django Rest Framework, которое хорошо работает с OIDC auth и человеческим взаимодействием с помощью django-oauth-toolkit.
Теперь я хочу добавить пару учетных записей сервисов, чтобы внешняя автоматизация могла делать запросы и создавать объекты. Согласно django-oauth-toolkit,
Грант Client Credential подходит для межмашинной аутентификации.
Итак, я реализовал этот тип гранта и протестировал его с помощью следующего скрипта:
client_id='axXSSBVuvOyGVzh4PurvKaq5MHXMm7FtrHgDMi4u'
secret='hun***2'
credential="${client_id}:${secret}"
CREDENTIAL=$(printf '%s' "$credential" | base64)
export CREDENTIAL
(
set -x
r=$(
curl "http://[::1]:8080/o/token/" \
-H "Authorization: Basic ${CREDENTIAL}" \
-H "Cache-Control: no-cache" \
-H "Content-Type: application/x-www-form-urlencoded" \
-X POST \
-d "grant_type=client_credentials" \
-d 'user=2'
)
access_token=$(jq -r '.access_token' <<< "$r")
curl -H "Authorization: Bearer ${access_token}" -H "Cache-Control: no-cache" 'http://[::1]:8080/notify/riskimpacts/'
)
и ответ - HTTP 403:
{"detail":"You do not have permission to perform this action."}
Он аутентифицирует, но не авторизует доступ к каким-либо представлениям, потому что нет пользователя, связанного с этими учетными данными. На самом деле, django-oauth-toolkit удаляет пользователя из запроса, даже если он должен быть, так что на самом деле не может быть пользователя, связанного с созданным здесь маркером доступа.
Однако все разрешения django-rest-фреймворка, кроме самых открытых (практически анонимных), требуют наличия пользователя.
В других описаниях систем authz, о которых я читал, есть полезный термин "принципал". Принципал может быть пользователем, но может быть и чем-то другим, что взаимодействует с системой и может иметь права и полномочия. В большинстве описаний клиентских учетных данных, которые я читал...
- https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/
- https://aaronparecki.com/oauth-2-simplified/#client-credentials
- https://oauth.net/2/grant-types/client-credentials/
- https://developer.okta.com/blog/2018/06/06/node-api-oauth-client-credentials
...описывают поток как нечто вроде от имени сервиса вместо пользователя. Но это означает, что служба является принципалом. Поэтому, предположительно, мы захотим предоставить некоторое разрешение сервису-принципалу вместо пользователя-принципала.
Я, наверное, неправильно понял суть предоставления клиентских полномочий, поэтому у меня есть несколько вопросов:
- Является ли клиентский мандат подходящим подходом для аутентификации между сервисами, когда вы хотите, чтобы два сервиса использовали один общий секрет?
- ...Если да, то в django-oauth-toolkit/django-rest-framework мы должны создать пользовательский класс разрешения (основанный на области видимости, возможно?), чтобы клиентский мандат мог иметь доступ к объекту(ам), или есть собственный или стандартный (но не анонимный) способ для клиентского мандата получить доступ к объекту? .
- ...Иначе, какой сценарий использования клиентских учетных данных помогает понять разницу, и какой подход к аутентификации между сервисами имеет больше смысла?