【问题标题】:In an xpage get a picture from a database where I don't have access to (acl)在 xpage 中从我无权访问的数据库中获取图片(acl)
【发布时间】:2013-04-18 08:56:49
【问题描述】:

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

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

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

【问题讨论】:

    标签: xpages


    【解决方案1】:

    另一种选择是使用 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 的浏览器上工作,因为他在每个页面上都使用了这种技术来制作公司徽标该站点:他没有直接链接到徽标 JPG,而是链接到一个 PHP 文件,该文件获取 IP、引用者、用户代理等,将所有元数据写入 MySQL 数据库,然后最终将徽标的字节流式传输到浏览器。这显然超出了您想要完成的范围,但我想您可能会觉得有趣的是,这种类型的用例现在在 XPages 中相当简单。

    【讨论】:

    • 阅读整个答案,斯文。 ;) "com.acme.xsp.util.StreamUtil 指的是一个 Java 便利类,用于将一个流流水线化到另一个流:"
    • 对不起,我的错。始终阅读代码,而不是 ;-)
    【解决方案2】:

    这可以使用 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>
    

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

    【讨论】:

    • 这样工作能省钱吗?看来我可以连接到没有标记公共访问权限的视图。我还可以打开没有设置 $PublicAccess 标志的文档。我只需要设置公共访问读取数据库上的公共文档。
    • 正确,您需要提供匿名公共访问权限(并将 XPage 标记为公共访问权限)。安全吗?与许多其他选项一样,它是一个选项 - 以及它的使用方式取决于开发人员:-)
    【解决方案3】:

    基本上这是不可能的。

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

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

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

    马特

    【讨论】:

    • Matt,我不想授予对数据库的访问权限,因为数据库中的某些数据不是供公众访问的。当字段包含某个字段时,如何在某些文档上设置 $PublicAccess 标志价值 ? (感谢您在 BLUG 的会议!)
    • 您可以简单地将计算文本字段添加到名为 $PublicAccess 的文档中,如果您希望对文档进行公共访问,则将其计算为“1”,否则计算为“0”。请记住,您希望用户通过其访问文档的任何视图也需要在其安全性上设置公共访问权限。
    • 我理解的很好吗?当我设置视图“对公共访问用户可用”时,这些用户只会看到 $PublicAccess 标志设置为“1”的文档。他们不会看到其他文件?
    • 只要 Anonymous 设置了 Read Public Documents 并且访问文档的视图也设置为允许公共访问,那么可以。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 2016-08-25
    • 1970-01-01
    相关资源
    最近更新 更多