Как сделать так, чтобы сервлет Jackrabbit WebDAV позволял редактировать с помощью Microsoft Word?

Я пытаюсь открыть репозиторий Jackrabbit Oak через сервлет. Хотя я могу успешно извлекать и редактировать .docx файл с помощью LibreOffice Writer, Microsoft Word не работает.

Я использую:

  • Дуб Кролик версия 1.8.4
  • Jackrabbit версия 2.17.5
  • LibreOffice Writer версии 6.1.3.2

Не работает версия Word:

  • Версия 1708
  • Microsoft Office 365 профессиональный плюс.

Я обращаюсь к документам одинаково в обоих редакторах, используя диалог открытого документа и вставляя http://localhost:8080/helloworld-singleton/repository/default/test.docx

Я установил простой сервлет, используя OpenSecurityProvider, который предоставляет репозиторий, копирующий локальную копию простого документа .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();
  }
}

Этот сервлет настраивается с помощью следующего 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, и у меня не возникло проблем с сохранением документов через Word.

В качестве возможного объяснения при внутренней отладке в Jackrabbit заметная разница между редакторами заключается в том, что LibreOffice Writer отправляет более null в заголовке Authorization, тогда как Word отправляет Bearer в заголовке Authorization для нескольких своих запросов. Затем все эти запросы игнорируются за исключением org.apache.jackrabbit.webdav.DavException: Unable to decode authorization.

Кто-нибудь знает, почему Word в этом случае не работает должным образом?


person Søren    schedule 03.01.2019    source источник
comment
FWIW, но не связанного с вашей проблемой: не используйте нестабильные версии Jackrabbit (2.17 == odd == unstable) в производственном коде.   -  person Julian Reschke    schedule 03.01.2019


Ответы (1)


Я подтверждаю, что «Авторизация: носитель» не поддерживается в 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.

Теперь нужно сделать лучшую реализацию ...

person morbac    schedule 09.07.2019
comment
Здравствуйте, вы можете переопределить реализацию CredentialsProvider в своем проекте, поэтому нет необходимости изменять источник Jackrabbit. Мне удалось это сделать, но я не могу открыть документ Word. Удалось ли вам открыть / редактировать непосредственно в Word? - person Beppe C; 13.03.2020