Как аутентифицировать пользователей exist-db в RESTXQ

(полный перефраз - раз нет ответа): Я разрабатываю приложение exist-db с аутентификацией пользователя и RESTXQ. Мои пользователи входят в систему через функцию login: set-user из модуля входа в систему. Вот фрагмент из контроллера:

import module namespace login="http://exist-db.org/xquery/login" at "resource:org/exist/xquery/modules/persistentlogin/login.xql";

declare variable $local:login_domain := "org.exist-db.superApp";
declare variable $local:user := $local:login_domain || '.user';

let $logout := request:get-parameter("logout", ())
let $set-user := login:set-user($local:login_domain, (), false())

это отлично работает. Если я позвоню, например, xmldb: get-current-user () в любом месте приложения: function () Я получаю имя пользователя, вошедшего в систему в данный момент.

У меня также есть модуль RESTXQ с парой функций, которые динамически вызываются через URL-адрес запросами AJAX. Некоторые из этих действий (удаление xml-элементов в данных, добавление новых коллекций ...) весьма критичны. Я не хочу, чтобы гости (или пользователи с неправильными правами) могли просто вызывать эти URL-адреса RESTXQ для манипулирования данными - поэтому RESTXQ должен быть защищен, и он должен дважды проверить: разрешено ли текущему авторизованному пользователю изменять определенные ресурсы / коллекции?

Если я позвоню, например, xmldb: get-current-user () в любой функции RESTXQ, я всегда получаю «гость», все функции диспетчера безопасности (sm) также указывают, что в RESTXQ нет сведений о текущем входе пользователя в систему. Только если я делаю что-то вроде xmldb: login ("/ db", "username", "password") в каждой функции RESTXQ, RESTXQ, кажется, знает, что кто-то вошел в систему, но имена пользователей и пароли не должны постоянно передаваться туда и обратно через URL-адрес - но без передачи этих данных функции RESTXQ, похоже, не знают об этом (верно?).

Итак, как я могу убедиться, что RESTXQ позволяет только аутентифицированным пользователям изменять данные (без того, чтобы пользователям приходилось проходить аутентификацию несколько раз и без необходимости передавать данные аутентификации в RESTXQ по каждому запросу) ?.

пример варианта использования: мне нужна функция RESTXQ, которая получает строку поиска ($ text) и путь к коллекции ($ path) в качестве входных данных, теперь она проверяет все файлы xml в $ path: Если текущие зарегистрированные -in-user (должен быть аутентифицирован!) имеет доступ для записи в файл, удалить все узлы, содержащие $ text, и вернуть пользователю некоторый ответ JSON ...

У меня есть несколько таких функций (перемещение, удаление и добавление данных, добавление новых коллекций ...), они работают хорошо, за исключением выделенной жирным шрифтом части: я не получаю этого Если. Есть идеи?

PS: эта тема в списке рассылки eXist задает тот же вопрос. Здесь @adamretter предлагает ограничить сам файл модуля RESTXQ, чтобы пользователям предлагалось (повторно) аутентифицироваться при вызове функции - даже если они уже использовали постоянный вход в систему. Вот что мне не нравится:

  1. Я не хочу, чтобы моим пользователям приходилось входить в систему несколько раз (это идея сделать вещи как можно более динамичными - например, с помощью RESTXQ)
  2. запрашиваемый вход в систему (для выполнения RESTXQ) и предыдущий вход в систему (постоянный) через модуль входа теперь могут отличаться!
  3. даже если пользователь выходит из системы в приложении, RESTXQ все равно предоставляется доступ, потому что запрашиваемая аутентификация ничего не знает о выходе. Если новый пользователь регистрируется (не в приглашении, а через модуль входа в систему), он все еще имеет доступ к RESTXQ, потому что это не запрашивается повторно (и я не знаю, как «выйти из системы» при этом запросе, по-видимому, параллельная секунда авторизоваться).
  4. Я могу таким образом ограничить весь модуль RESTXQ, но я до сих пор не знаю, как задать вопрос в функции RESTXQ: «какие права доступа есть у текущего пользователя на ресурс A, B, C ...

person J. Schäuble    schedule 30.11.2017    source источник
comment
@ j-schäuble Сегодня я столкнулся с тем же вопросом, который вы задали год назад. Как вам удалось это решить? Спасибо!   -  person jbrehr    schedule 10.08.2019


Ответы (2)


Надеясь, что это поможет другим:

При отправке AJAX-запроса добавьте заголовок:

[...]
headers: {'Authorization': 'Basic ' + btoa(username + ':' + password)},
[...]

Это приведет к входу пользователя в систему с указанными учетными данными (если они верны). Затем в вашей функции RESTXQ вы можете получить доступ к данным пользователя через sm:id():

declare namespace sm = "http://exist-db.org/xquery/securitymanager";
[...]
let $username := xs:string(sm:id()//sm:real//sm:username)

Вы должны использовать информацию под sm:real, поскольку setuid или setgid могут маскировать реальные значения.

Обратите внимание, что данные для входа в систему не сохраняются, поэтому вам нужно отправлять их с каждым запросом AJAX, который вы делаете.

person dariok    schedule 21.08.2018
comment
Часть btoa, вероятно, сэкономила мне несколько часов, большое вам спасибо за это. Документация для этого чертовски скудна ... - person ForWiz; 09.07.2021

API RESTXQ не имеет состояния. Таким образом, вам необходимо аутентифицироваться по каждому запросу. Это сделано намеренно и сделано специально, чтобы каждый вызов RESTXQ мог эффективно работать изолированно.

В этом нет ничего необычного, поскольку другие API, такие как Amazon S3, также требуют, чтобы такая аутентификация предоставлялась при каждом запросе.

То, как ваши пользователи проходят аутентификацию в RESTXQ и как вы запрашиваете у них учетные данные запроса (и, возможно, их повторно используете), выходит за рамки RESTXQ API и вместо этого считается проблемой клиента, которую вам необходимо решить в своем собственном приложении.

person adamretter    schedule 11.08.2019