如何在RESTXQ

时间:2017-11-30 16:19:10

标签: authentication exist-db securitymanager restxq

(完全改写 - 因为没有答案): 我正在使用用户身份验证和RESTXQ开发一个exists-db应用程序。我的用户通过登录模块中的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()在app中的任何位置:function()我得到当前登录的用户名。

我还有一个RESTXQ模块,其中有几个函数可以通过AJAX请求通过URL动态调用。其中一些操作(删除数据中的xml元素,添加新集合......)非常关键。我不希望guest(或权限错误的用户)只能调用这些RESTXQ URL来操作数据 - 所以RESTXQ必须是安全的,并且应该进行双重检查:是否允许修改特定资源的当前登录用户/收藏?

如果我打电话,例如xmldb:任何RESTXQ函数中的get-current-user(),我总是得到“guest”,所有安全管理器(sm)函数也表明在RESTXQ中没有关于当前用户登录的知识。只有当我在每个RESTXQ函数中执行类似xmldb:login(“/ db”,“username”,“password”)的操作时,RESTXQ似乎知道某人已登录,但用户名和密码不应经常来回传递URL - 但是没有传递这些数据,RESTXQ函数似乎不知道它(对吧?)。

那么我如何确定,RESTXQ只允许经过身份验证的用户更改数据(无需用户多次进行身份验证,而无需在每次请求时将身份验证数据传递给RESTXQ)?.

示例用例: 我想要一个RESTXQ函数,它获取一个搜索字符串($ text)和一个collection-path($ path)作为输入,现在它检查$ path中的所有xml文件:如果当前登录用户(必须经过身份验证!)具有对文件的写入权限,删除包含$ text的所有节点并向用户返回一些JSON响应......

我有多个这样的功能,(移动,删除和添加数据,添加新的集合......),除了粗体部分外,它们的效果很好:我没有得到如果。想法?

PS:这topic on the eXist mailing list提出了同样的问题。这里@adamretter sugest限制RESTXQ模块文件本身,因此在调用函数时会提示用户(重新)进行身份验证 - 即使他们已经使用了持久登录。这是我不喜欢的:

  1. 我不希望我的用户多次登录(这是让事情尽可能动态的想法 - 例如使用RESTXQ)
  2. 提示登录(用于执行RESTXQ)和之前登录(persitent)通过登录模块现在可能有所不同!
  3. 即使用户在应用程序中注销,RESTXQ仍然被授予访问权限,因为提示身份验证对注销一无所知。如果新用户记录(不是在提示中,而是通过登录模块),她仍然可以访问RESTXQ,因为没有重新提示(并且我不知道如何“注销”这个提示,看似平行的第二个登录)。
  4. 我可以用这种方式限制整个RESTXQ模块,但我仍然不知道如何在RESTXQ函数中询问:“当前用户对资源A,B,C的访问权限是什么...

2 个答案:

答案 0 :(得分:0)

希望这对其他人有帮助:

进行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下的信息,因为setuidsetgid可能会掩盖实际值。

请注意,登录信息不会存储,因此您需要将其与每个发出的AJAX请求一起发送。

答案 1 :(得分:0)

RESTXQ API是无状态的。因此,您需要对每个请求进行身份验证。这种情况是有意的,并且是有意设计的,因此每个RESTXQ调用都可以有效地独立运行。

这很正常,因为其他API(例如Amazon S3)也要求在每次请求时都提供这种身份验证。

您的用户如何向RESTXQ进行身份验证以及如何提示他们输入请求凭据(并可能重用这些凭据)不在RESTXQ API的范围内,而是被视为您需要自己解决的客户端问题应用。