Частичный токен JWT при обновлении токена

В микросервисной архитектуре мы используем токены 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, немного абстрактны).


person Philipp    schedule 07.02.2019    source источник
comment
Это интересная проблема +1. Я вообще не знаю маскировки ключей, но что мешает вам просто использовать код, аналогичный тому, который вы использовали для создания исходного JWT? Кстати, как вы, наверное, уже знаете, вам нужно аннулировать предыдущий JWT, прежде чем выдавать новый токен доступа к документу. В противном случае старый все еще будет там.   -  person Tim Biegeleisen    schedule 07.02.2019
comment
что мешает вам просто использовать код, аналогичный тому, который вы использовали для создания начального JWT. Частичный токен должен быть сгенерирован через некоторое время после входа в систему (и я не хочу хранить учетные данные для входа).   -  person Philipp    schedule 07.02.2019
comment
Для повышения уровня безопасности приложения я бы: - Использовать короткие значения срока службы токена доступа - Использовать HTTP через SSL - Ограничить время ожидания сеанса пользователя. То, о чем вы думаете, подразумевает дополнительный уровень сложности (насколько я знаю), который может включать самостоятельное написание кода, связанного с безопасностью, для расширения протокола OIDC, что может привести к еще большим рискам.   -  person Xtreme Biker    schedule 07.02.2019
comment
@XtremeBiker: спасибо за список хороших практик (мы их уже применяем). Вы подразумеваете, что то, что мы хотим сделать, невозможно в Keycloak?   -  person Philipp    schedule 10.02.2019
comment
Нет ничего невозможного, keycloak имеет открытый исходный код, и вы даже можете изменить его исходный код, чтобы он делал то, что вы хотите, и перекомпилировать его. Я имею в виду, что, насколько я знаю, в протоколе openid Connect нет такой возможности.   -  person Xtreme Biker    schedule 10.02.2019
comment
Удалось ли вам получить данный ответ?   -  person Xtreme Biker    schedule 26.02.2019
comment
@XtremeBiker Большое спасибо за ваши огромные усилия! Мне нужно было быстрое решение, поэтому я реализовал свой собственный световой токен (он работает, но без Keycloak). AFAI понимает ваше решение, пользователь будет участвовать в предоставлении разрешения (т. Е. Алиса меняет политику, как в примере), так что это немного отличается?   -  person Philipp    schedule 04.03.2019
comment
Пожалуйста! Это был своего рода пример того, насколько мощной является конфигурация ресурсов с помощью этого инструмента, не предназначенная для вашего конкретного случая. В вашем случае вместо Алисы вам понадобится ваше приложение, назначающее ресурсы для конкретных пользователей (см. rel="nofollow noreferrer">глава 8.4 документации).   -  person Xtreme Biker    schedule 04.03.2019


Ответы (1)


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

person Xtreme Biker    schedule 16.02.2019