В микросервисной архитектуре мы используем токены JWT из keycloak. Теперь мы хотели бы получить второй токен доступа с меньшими правами (меньше требований/меньше ролей). Пример использования: новый токен доступа должен предоставлять своему владельцу доступ только к одному документу в хранилище документов. Почему? Чтобы ограничить ущерб, который может нанести кто-то, если он сможет украсть этот токен.
В идеале мы могли бы получить этот второй токен с помощью специального вызова refresh_token (пользователь, у которого есть токен обновления, имеет право получить токен полного доступа, поэтому он также должен иметь возможность получить токен частичного доступа). Как мы могли это сделать?
Использование областей, похоже, не работает: список заданных областей оценивается только при входе в систему (поэтому в момент обновления токена я не могу принять список областей).
Я также пытался понять https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_overview или RPT. Но, к сожалению, мне не хватает документации (и мои попытки не увенчались успехом).
Есть ли другие идеи? Или, может быть, хотя бы пример, показывающий, как это сделать?
Позднее отредактируйте, чтобы уточнить мой вопрос о RPT: https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_overview говорит:
... Службы авторизации Keycloak предоставляют расширения для OAuth2, позволяющие выдавать токены доступа на основе обработки всех политик, связанных с запрашиваемыми ресурсами или областями. Это означает, что серверы ресурсов могут обеспечивать доступ к своим защищенным ресурсам на основе разрешений, предоставленных сервером и удерживаемых токеном доступа. В службах авторизации Keycloak токен доступа с разрешениями называется токеном запрашивающей стороны или сокращенно RPT.
Можно ли использовать такой токен доступа с разрешениями для нашей цели?
В моих экспериментах я мог получить токен с помощью grant_type=urn:ietf:params:oauth:grant-type:uma-ticket . Но были некоторые проблемы:
Мне пришлось изменить некоторые настройки в keycloak, чтобы включить разрешения (до того, как он сказал бы "Клиент не поддерживает разрешения"). После того, как я внес эти изменения, мой обычный вызов входа в систему больше не работал (я мог проверить, пока мой токен был еще действителен). Мне пришлось поцарапать конфигурацию keycloak, чтобы продолжить работу.
Я не совсем понимаю модель разрешений, которую следует использовать для этой функции.
Был бы полезен сквозной пример (те, что в документации Keycloak, немного абстрактны).
Ответ 1 · рейтинг 1 · Xtreme Biker
Я зашел в документы, и то, что вы хотите, может быть достигнуто путем защиты вашего сервера ресурсов (вашего приложения), чтобы действовать как сервер ресурсов, защищенный UMA. Вот вам базовый пример того, чего можно достичь с помощью это:
Keycloak - это сервер авторизации, совместимый с UMA 2.0, который предоставляет большинство возможностей UMA.
В качестве примера рассмотрим пользователя Алису (владелец ресурса), использующего службу интернет-банкинга (сервер ресурсов) для управления своим банковским счетом (ресурсом). Однажды Алиса решает открыть свой банковский счет Бобу (запрашивающая сторона), профессиональному бухгалтеру. Однако у Боба должен быть доступ только для просмотра (области) учетной записи Алисы.
В качестве сервера ресурсов служба интернет-банкинга должна иметь возможность защитить банковский счет Алисы. Для этого он использует конечную точку регистрации ресурса Keycloak для создания ресурса на сервере, представляющего банковский счет Алисы.
В этот момент, если Боб попытается получить доступ к банковскому счету Алисы, в доступе будет отказано. Служба интернет-банкинга определяет несколько политик по умолчанию для банковских счетов. Один из них заключается в том, что только владелец, в данном случае Алиса, имеет доступ к своему банковскому счету.
Однако служба интернет-банкинга в отношении конфиденциальности Алисы также позволяет ей изменять определенные правила для банковского счета. Одна из этих политик, которую она может изменить, - определить, каким людям разрешено просматривать ее банковский счет. Для этого служба интернет-банкинга полагается на Keycloak, чтобы предоставить Алисе пространство, где она может выбирать людей и операции (или данные), к которым им разрешен доступ. В любой момент Алиса может отозвать доступ или предоставить Бобу дополнительные разрешения.
Затем используйте средства обеспечения соблюдения политики, чтобы активировать эту защиту:
Если ресурсный сервер защищен средством применения политики, он отвечает на запросы клиентов на основе разрешений, передаваемых вместе с токеном-носителем. Как правило, когда вы пытаетесь получить доступ к серверу ресурсов с токеном-носителем, которому не хватает разрешений на доступ к защищенному ресурсу, сервер ресурсов отвечает кодом состояния 401 и заголовком WWW-Authenticate.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}",
as_uri="https://${host}:${post}/auth/realms/${realm}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
Здесь есть две части, которые вам нужно сделать. Во-первых, нужно добавить применение политики для путей приложение, которое вы хотите защитить. Затем, и вот оно, соус, вам нужно настроить часть UMA. Хорошая часть UMA заключается в том, что она добавляет дополнительную систему тикетов в процесс авторизации, и эти тикеты назначаются для каждого ресурса (фактически, они назначаются, когда вы пытаетесь получить доступ к защищенному ресурсу).
Клиент запрашивает защищенный ресурс без отправки RPT
curl -X GET \
http://${host}:8080/my-resource-server/resource/1bfdfe78-a4e1-4c2d-b142-fc92b75b986f
Сервер ресурсов отправляет ответ обратно клиенту с билетом разрешения и параметром as_uri с расположением сервера Keycloak, на который должен быть отправлен билет для получения RPT. Сервер ресурсов отвечает билетом разрешения
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}",
as_uri="https://${host}:${post}/auth/realms/${realm}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
Таким образом, клиент запрашивает ресурс, и ему дается билет с указанием местоположения сервера Keycloak, чтобы обменять этот билет на RPT. Это клиент, отправляющий конечную точку токена, чтобы получить RPT:
curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "ticket=${permission_ticket} \
--data "submit_request=true"
Это даст вам RPT, который действителен только для доступа к ресурсу, который вы запросили в первый раз. Скажи это:
{
"authorization": {
"permissions": [
{
"resource_set_id": "d2fe9843-6462-4bfc-baba-b5787bb6e0e7",
"resource_set_name": "Hello World Resource"
}
]
},
"jti": "d6109a09-78fd-4998-bf89-95730dfd0892-1464906679405",
"exp": 1464906971,
"nbf": 0,
"iat": 1464906671,
"sub": "f1888f4d-5172-4359-be0c-af338505d86c",
"typ": "kc_ett",
"azp": "hello-world-authz-service"
}
Вам также потребуется управлять доступом пользователей к их ресурсам. Здесь это делается с помощью пользовательского интерфейса администратора, но вам может потребоваться правильно настроить его из вашего приложения, вызвав API Keycloak.