0

有没有办法让基于 xpages 的网页的 Web 用户能够显示(仅读取模式)数据库中的文档,而匿名用户在 acl 中没有访问权限。如果我有访问权限,我可以获取该文档,例如: https://servername/otherdatabase.nsf/O/"+thisid+"/$FILE/"+thisdocument

我想 SessionAsSigner 一定是可能的,但是如何?

其次,该用户有没有办法从匿名无权访问的数据库中查看视图?我该如何设置?

4

3 回答 3

9

另一种选择是使用 XAgent;例如,将beforeRenderResponse事件设置为以下内容:

var fileDb = sessionAsSigner.getDatabase((param.server || ""), param.path);
var fileDocument = fileDb.getDocumentByUNID(param.id);
var attachment = fileDocument.getAttachment(param.filename);
var inputStream = attachment.getInputStream();
var response = facesContext.getExternalContext().getResponse();
/* The following MIME type is generic, should work for all image types;
If you know what type the image will be, set a more specific MIME type */
response.setContentType("application/octet-stream");
var outputStream = response.getOutputStream();
com.acme.xsp.util.StreamUtil.copyStream(inputStream, outputStream);
inputStream.close();
outputStream.close();
attachment.recycle();
fileDocument.recycle();
facesContext.responseComplete();

com.acme.xsp.util.StreamUtil指用于将一个流流水线化到另一个流的 Java 便利类:

public class StreamUtil {
    public static void copyStream(InputStream input, OutputStream output) throws IOException {
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = input.read(buffer)) != -1) {
            output.write(buffer, 0, bytesRead);
        }
    }
}

因此,不是将您的图像标签直接链接到附件,而是如下所示:

<xp:image url="/download.xsp?server=ACME01&amp;path=images.nsf&amp;id=OU812&amp;filename=photo.jpg" />

这种方法还可以为您提供其他选择:记录访问给定文件的次数、引用 URL(以防您想要实现在 Google 搜索图像时有时会看到的“无热链接”图像替换),或者您想要的任何东西.

举个具体的例子,大约十年前,我看到一位同事在内部实现了一个与 Google Analytics 相当的基本功能,甚至可以在不支持 JavaScript 的浏览器上工作,因为他在网站的每个页面上都使用了这种技术来制作公司徽标:他没有直接链接到 logo JPG,而是链接到一个 PHP 文件,该文件获取 IP、referer、用户代理等,将所有元数据写入 MySQL 数据库,然后最终将 logo 的字节流式传输到浏览器。这显然超出了您想要完成的范围,但我想您可能会发现有趣的是,这种类型的用例现在在 XPages 中相当简单。

于 2013-04-18T11:27:17.893 回答
4

这可以使用 sessionAsSigner 并且例如重复。如果 XPage 在同一个数据库中,请确保将 XPage 标记为可供公共访问。以下简单示例将显示视图列中的内容和文档中的图像:

<xp:repeat id="protectedView" rows="15" removeRepeat="true" var="rowEntry" disableOutputTag="true">
    <xp:this.value><![CDATA[#{javascript:
        var thisDb = sessionAsSigner.getDatabase(database.getServer(), database.getFilePath());
        var aView = thisDb.getView("protectedView");
        return staffView.getAllEntries(); // return collection of docs
    }]]></xp:this.value>
        <xp:text>
            <xp:this.value><![CDATA[#{javascript:rowEntry.getColumnValues().elementAt(1)}]]></xp:this.value>
        </xp:text>
        <xp:br />
        <xp:text>
            <xp:this.value><![CDATA[#{javascript:rowEntry.getColumnValues().elementAt(2)}]]></xp:this.value>
        </xp:text>
        <xp:br />
        <xp:inputRichText id="inputRichText1" readonly="true">
            <xp:this.value><![CDATA[#{javascript:
                // wrap NotesDocument into NotesXspDocumenet to easily display picture
                wrapDocument(rowEntry.getDocument()).getValue("Picture");}]]></xp:this.value>
        </xp:inputRichText>
</xp:repeat>

我使用wrapDocument XSnippet将 NotesDocument 转换为 NotesXspDocument。

于 2013-04-18T09:43:19.013 回答
2

本质上这是不可能的。

您可以使用 sessionAsSigner 构造 URL,但是当用户尝试访问文档/图像时,他们将获得未经授权的异常。

显示数据视图的唯一方法是使用 sessionAsSigner 将视图的内容读入范围变量(或 bean),然后显示一个重复控件,该控件引用范围变量中的数据,而不是直接引用视图。

更大的问题是你为什么要这样做。如果 Anonymous 无法访问相关数据库,那么这是有充分理由的。另一种选择是考虑在要授予匿名访问权限的文档/视图上使用 $PublicAccess 标志。然后在 ACL 上,只要 Anonymous 可以读取公共数据,那么他们仍然无法访问数据库。

马特

于 2013-04-18T09:06:06.493 回答