Я пытаюсь аутентифицировать запросы RADIUS с помощью RESTful API (предоставленного Заказчиком) с помощью rlm_rest.
Проблема, с которой я столкнулся, заключается в том, что Формат ответа JSON (предоставленного Заказчиком REST API) отличается от формата по умолчанию rlm_rest (указанного в и т. д. / Raddb / с включенными модами / отдых).
Конфигурация моего виртуального сервера, как показано ниже:
authorize {
...
...
rest
if (ok) {
update control {
Auth-Type := rest
}
}
}
authorize {
uri = "https://3rd-party-API/auth"
method = 'post'
body = 'json'
chunk = 0
tls = ${..tls}
data = '{
"code": 1,
"identifier": %I,
"avps": {
"User-Name": ["%{User-Name}"],
"NAS-IP-Address": ["%{NAS-IP-Address}"],
"Called-Station-Id": ["%{Called-Station-Id}"],
"Calling-Station-Id": ["%{Calling-Station-Id}"],
"NAS-Identifier": ["%{NAS-Identifier}"]
}
}'
}
/ sbin / radiusd -Xxx
Код ответа HTTP
200
JSON Body
{
"code": "2",
"identifier": "91",
"avps": {
"Customer-Attributes": "Hello"
...
...
"Acct-Interim-Interval": "300"
}
}
Структура JSON отличается от примера, и синтаксический анализ xlat "код" "идентификатор" "avps"
И, конечно же, xlat не находит атрибутов, соответствующих словарю, а также не может найти «avps» и не будет копать глубже.
Так что мне было интересно, есть ли способ
Пожалуйста, сообщите, есть ли обходной путь. Спасибо!
В FreeRADIUS версии 4 есть модуль rlm_json, который реализует настраиваемый язык запросов узлов на основе xpath (jpath), он чрезвычайно ограничен и поддерживает только некоторые очень простые запросы (не стесняйтесь улучшать его с помощью PR :)).
Ниже приведен пример, который я взял из своей библиотеки конфигураций клиентов. Здесь вы можете увидеть, как он извлекает два ключа (externalID и macAddress) из корневого уровня документа JSON и назначает их нескольким настраиваемым атрибутам (Subscriber-ID и Provisioned-MAC).
map json "%{rest_api:https://${modules.rest[rest_api].server}/admin/api/${modules.rest[rest_api].api_key}/external/getDeviceBySerialNumber?certificateSerialNumber=%{lpad:&TLS-Client-Cert-Serial 40 0}}" {
&Subscriber-ID := '$.externalId'
&Provisioned-MAC := '$.macAddress'
}
Расширение xlat также можно изменить для отправки данных тела HTTP. Просто поставьте пробел после URL-адреса и передайте свой собственный большой двоичный объект JSON.
rest_api - это просто экземпляр rlm_rest. Используемое там расширение - это расширение модуля rlm_rest. Я думаю, что rlm_rest нормально поддерживает HTTP / 2. Может потребоваться дополнительная опция, переданная libcurl для включения конвейерной обработки, но это все.
Да, я только что это проверил. По крайней мере, в v4.0.x мы можем относительно легко добавить конвейерную обработку. Просто нужно настроить несколько параметров на многофункциональной ручке, и все готово.
Спасибо ... Теперь я заметил, что реализация rlm_rest изменилась с curl_easy на curl_multi_interface в FreeRADIUS 4.0.x. Это делает мультиплексирование HTTP / 2 относительно простым!
Другой вопрос, как мне указать метод HTTP, если я собирался использовать "% {rest_api: REST_URI JSON_BODY"? Я заметил, что есть uri и body, но нет метода HTTP.
и вуаля! - github.com/FreeRADIUS/freeradius-server/commit/…
Спасибо за щедрую помощь. Буду использовать!
Для остальных XLAT я считаю, что вы можете использовать %{rest_api:HTTP_METHOD REST_URI JSON_BODY}
.
Без проблем! Дайте мне знать, если что-то нужно настроить. Не могли бы вы принять ответ, если считаете его правильным :)
Выглядит отлично :) Однако сейчас наша команда использует rlm_rest. Основная причина в том, что в этом случае мы реализовали мультиинтерфейс curl для поддержки мультиплексирования HTTP / 2. Итак, я предполагаю, что json должен быть результатом rlm_rest. Есть ли способ передать результат rlm_rest в rlm_json?