如何使Jackrabbit WebDAV servlet允许使用Microsoft Word编辑?

时间:2019-01-03 08:39:45

标签: java ms-word webdav jackrabbit jackrabbit-oak

我正在尝试通过servlet公开Jackrabbit Oak存储库。虽然我可以使用LibreOffice Writer成功检索和编辑.docx文件,但Microsoft Word无法正常工作。

我正在使用:

  • Jackrabbit Oak 1.8.4版
  • Jackrabbit版本2.17.5
  • LibreOffice Writer 6.1.3.2版

无法使用的Word版本是:

  • 版本1708
  • Microsoft Office 365 ProPlus。

通过使用打开的文档对话框并放入http://localhost:8080/helloworld-singleton/repository/default/test.docx

,我在两个编辑器中都以相似的方式访问文档

我已经使用OpenSecurityProvider设置了一个简单的servlet,该servlet公开了一个存储库,该存储库复制了一个简单的.docx文档的本地副本:

public class SimpleWebdavServlet extends SimpleWebdavServlet {
  private static Repository repository;

  public Repository getRepository() {
    return getRepositoryInternal();
  }

  static Repository getRepositoryInternal() {
    try {
      if (repository == null) {
        Jcr jcr = new Jcr().with(new OpenSecurityProvider());
        repository = jcr.createRepository();
        Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));

        Node rootNode = session.getRootNode();
        if (!rootNode.hasNode("test.docx")) {
          importFile(session, rootNode);
        }
        session.save();
      }
    } catch (FileNotFoundException | RepositoryException e) {
      e.printStackTrace();
    }
    return repository;
  }

  private static void importFile(Session session, Node rootNode) throws FileNotFoundException, RepositoryException {
    FileInputStream is = new FileInputStream(new File("C:\\test.docx"));
    ValueFactory valueFactory = session.getValueFactory();
    Binary contentValue = valueFactory.createBinary(is);
    Node fileNode = rootNode.addNode("test.docx", "nt:file");
    fileNode.addMixin("mix:referenceable");
    Node resNode = fileNode.addNode("jcr:content", "nt:resource");
    resNode.setProperty("jcr:mimeType", "application/octet-stream");
    resNode.setProperty("jcr:data", contentValue);
    Calendar lastModified = Calendar.getInstance();
    lastModified.setTimeInMillis(lastModified.getTimeInMillis());
    resNode.setProperty("jcr:lastModified", lastModified);
    session.save();
  }
}

此servlet是通过以下web.xml配置的:

<web-app>
  <display-name>Jackrabbit Webdav</display-name>
  <servlet>
    <servlet-name>Webdav</servlet-name>
    <servlet-class>org.jboss.as.quickstarts.singleton.SimpleWebdavServlet</servlet-class>
    <init-param>
      <param-name>resource-path-prefix</param-name>
      <param-value>/repository</param-value>
    </init-param>
    <init-param>
      <param-name>missing-auth-mapping</param-name>
      <param-value>admin:admin</param-value>
    </init-param>
    <init-param>
      <param-name>resource-config</param-name>
      <param-value>/WEB-INF/config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Webdav</servlet-name>
    <url-pattern>/repository/*</url-pattern>
  </servlet-mapping>
</web-app>

使用此代码,我希望能够在Word中打开文档,对其进行编辑,然后将更改保存到服务器中-就像在LibreOffice Writer中一样。

与Word相比,该文档以受保护的视图打开,尝试保存更改,仅提示您保存该文档的本地副本。

我曾尝试为另一个JCR实现ModeShape创建一个类似的servlet,并且通过Word在持久文档上没有遇到任何问题。

作为在Jackrabbit内部进行调试的一种可能解释,编辑器之间的显着区别是LibreOffice Writer通过null标头中的Authorization发送,而Word在{ {1}}标头中的几个请求。由于Bearer

的异常,所有这些请求都将被忽略

有人知道为什么在这种情况下Word无法按预期工作吗?

1 个答案:

答案 0 :(得分:0)

我确认jackrabbit-jcr-server不支持“授权:承载”。 BasicCredentialsProvider类仅支持“登录:密码” base64编码的基本身份验证。

出于测试目的,我修改了getCredentials()方法,以在收到承载授权时强制使用“ admin / admin”进行基本身份验证:

...
if (authStr.length >= 2 && authStr[0].equalsIgnoreCase(HttpServletRequest.BASIC_AUTH)) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    Base64.decode(authStr[1].toCharArray(), out);
    String decAuthStr = out.toString("ISO-8859-1");
    int pos = decAuthStr.indexOf(':');
    String userid = decAuthStr.substring(0, pos);
    String passwd = decAuthStr.substring(pos + 1);
    return new SimpleCredentials(userid, passwd.toCharArray());
} else if (authStr.length >= 1 && authStr[0].equalsIgnoreCase("Bearer")) {
    return new SimpleCredentials("admin", "admin".toCharArray());
}
throw new ServletException("Unable to decode authorization.");
...

此后,我重新编译了jackrabbit-jcr-server(使用maven)并重新部署了它,然后使用MS Word进行直接编辑。

现在应该执行更好的实现...