在xpage中,从我没有访问(acl)权限的数据库中获取图片



是否有一种方法为一个基于网页的网页用户能够显示(只读模式)一个文档,是在一个数据库中匿名没有访问acl。如果我有权限,我可以获取文档,例如:https://servername/otherdatabase.nsf/O/"+thisid+"/$FILE/"+thisdocument

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

其次,是否有一种方法可以让这个用户从数据库中看到匿名用户无法访问的视图?如何设置呢?

另一种选择是使用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(如果您想实现"无热链接"图像替换,您有时会在谷歌搜索图像时看到),或者任何您想要的。

作为一个具体的例子,大约十年前我看到一个同事实现一个基本的内部相当于谷歌分析,即使在浏览器不支持JavaScript,因为他这种技术用于网站的每一页都公司的标志,而不是直接连接到标志JPG,他与一个PHP文件,抓起IP,推荐人,用户代理,等,写所有的元数据到一个MySQL数据库,最后流标识的字节到浏览器。这显然超出了您想要完成的范围,但我认为您可能会发现有趣的是,这种类型的用例现在在XPages中相当简单。

这可以使用sessionAsSigner和例如repeat。如果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。

基本上这是不可能的。

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

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

更大的问题是你为什么要这样做。如果匿名者不能访问有问题的数据库,那么这是一个很好的理由。另一种替代方法是考虑在您希望给予匿名访问权限的文档/视图上使用$PublicAccess标志。那么在ACL上,只要Anonymous可以读取公共数据,那么他们仍然不能访问数据库。

马特

最新更新