Как предоставить права клиенту, который не является пользователем в 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, о которых я читал, есть полезный термин "принципал". Принципал может быть пользователем, но может быть и чем-то другим, что взаимодействует с системой и может иметь права и полномочия. В большинстве описаний клиентских учетных данных, которые я читал...

  1. https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/
  2. https://aaronparecki.com/oauth-2-simplified/#client-credentials
  3. https://oauth.net/2/grant-types/client-credentials/
  4. https://developer.okta.com/blog/2018/06/06/node-api-oauth-client-credentials

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

Я, наверное, неправильно понял суть предоставления клиентских полномочий, поэтому у меня есть несколько вопросов:

  1. Является ли клиентский мандат подходящим подходом для аутентификации между сервисами, когда вы хотите, чтобы два сервиса использовали один общий секрет?
  2. ...Если да, то в django-oauth-toolkit/django-rest-framework мы должны создать пользовательский класс разрешения (основанный на области видимости, возможно?), чтобы клиентский мандат мог иметь доступ к объекту(ам), или есть собственный или стандартный (но не анонимный) способ для клиентского мандата получить доступ к объекту?
  3. .
  4. ...Иначе, какой сценарий использования клиентских учетных данных помогает понять разницу, и какой подход к аутентификации между сервисами имеет больше смысла?
Вернуться на верх