Как правильно реализовать веб-скрипт POST в Alfresco 5, не вызывая исключения CSRF?

Я создал расширение модуля для использования с Alfresco 5 Community Edition. Все отлично работает, я позаботился о своих методах .get, и они отображаются правильно.

На странице у меня есть кнопка, которая отправляет обратно на сервер для отображения результата (сейчас она пуста для тестирования). Когда я нажимаю кнопку, я получаю ошибку сервера:

javax.servlet.ServletException: Possible CSRF attack noted when comparing token in session and request header. Request: POST /share/service/components/console/reset-dashboards
    at org.alfresco.web.site.servlet.CSRFFilter$AssertTokenAction.run(CSRFFilter.java:827)
    at org.alfresco.web.site.servlet.CSRFFilter.doFilter(CSRFFilter.java:312)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2466)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2455)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

Проверяя веб-скрипты uri по адресу http://localhost:8080/share/page/index/uri/components/console/reset-dashboards, я вижу, что все зарегистрировано правильно.

Reset Dashboards
GET /share/page/components/console/reset-dashboards
Description:    Dashboard Tools - Reset All Dashboards To Default
Authentication: none
Transaction:    none
Format Style:   any
Default Format: html
Id: com/company/components/console/dashboard-tools/reset-dashboards.get
Description:    classpath:alfresco/site-webscripts/com/company/components/console/dashboard-tools/reset-dashboards.get.desc.xml

Reset Dashboards POST
POST /share/page/components/console/reset-dashboards
Description:    Dashboard Tools - Reset All Dashboards To Default POST
Authentication: user
Transaction:    required
Format Style:   any
Default Format: json
Id: com/company/components/console/dashboard-tools/reset-dashboards.post
Description:    classpath:alfresco/site-webscripts/com/company/components/console/dashboard-tools/reset-dashboards.post.desc.xml

Это информация для веб-скрипта GET:

Script Properties
Id: com/company/components/console/dashboard-tools/reset-dashboards.get
Short Name: Reset Dashboards
Description:    Dashboard Tools - Reset All Dashboards To Default
Authentication: none
Transaction:    none
Method: GET
URL Template:   /components/console/reset-dashboards
Format Style:   any
Default Format: html
Negotiated Formats: [undefined]
Implementation: class org.springframework.extensions.webscripts.DeclarativeWebScript
Extensions: [undefined]

Store: classpath:alfresco/site-webscripts

File: com/company/components/console/dashboard-tools/reset-dashboards.get.desc.xml

<webscript>
    <shortname>Reset Dashboards</shortname>
    <description>Dashboard Tools - Reset All Dashboards To Default</description>
    <url>/components/console/reset-dashboards</url>
    <family>admin-console</family>
</webscript>

File: com/company/components/console/dashboard-tools/reset-dashboards.get.html.ftl

<@markup id="css" >
<#-- CSS Dependencies -->
    <@link href="${url.context}/res/components/console/application.css" group="console"/>
</@>

<@markup id="js">
<#-- JavaScript Dependencies -->
    <@script src="${url.context}/res/components/console/consoletool.js" group="console"/>
    <#--<@script src="${url.context}/res/components/console/application.js" group="console"/>-->
</@>

<@markup id="widgets">
    <@createWidgets group="console"/>
</@>

<@markup id="html">
    <#assign el=args.htmlid?html>
    <form id="${el}-options-form" action="${url.context}/service/components/console/reset-dashboards" method="post">
        <div class="buttons">
            <button id="${el}-apply-button" name="apply">${msg("button.reset")}</button>
        </div>
    </form>
</@>

File: com/company/components/console/dashboard-tools/reset-dashboards.get.js

function main()
{
}

main();

Store: classpath:surf/webscripts

[No implementation files]

Store: classpath:webscripts

[No implementation files]

Это информация для веб-скрипта POST:

Script Properties
Id: com/company/components/console/dashboard-tools/reset-dashboards.post
Short Name: Reset Dashboards POST
Description:    Dashboard Tools - Reset All Dashboards To Default POST
Authentication: user
Transaction:    required
Method: POST
URL Template:   /components/console/reset-dashboards
Format Style:   any
Default Format: json
Negotiated Formats: [undefined]
Implementation: class org.springframework.extensions.webscripts.DeclarativeWebScript
Extensions: [undefined]

Store: classpath:alfresco/site-webscripts

File: com/company/components/console/dashboard-tools/reset-dashboards.post.desc.xml

<webscript>
    <shortname>Reset Dashboards POST</shortname>
    <description>Dashboard Tools - Reset All Dashboards To Default POST</description>
    <format default="json" />
    <url>/components/console/reset-dashboards</url>
    <authentication>user</authentication>
</webscript>

File: com/company/components/console/dashboard-tools/reset-dashboards.post.json.ftl

{
    "success": ${success?string},
    "message": "<#if errormsg??>${errormsg}</#if>"
}

File: com/company/components/console/dashboard-tools/reset-dashboards.post.json.js

function main()
{
    model.success = true;
}

main();

Store: classpath:surf/webscripts

[No implementation files]

Store: classpath:webscripts

[No implementation files]

Опять же, когда я нажимаю кнопку на странице для публикации в веб-скрипте, это дает мне исключение Possible CSRF attack. Как это исправить? Можно ли это сделать внутри файла расширения модуля jar?

ОБНОВЛЕНИЕ

Я заметил, что все другие скрипты, публикуемые как часть Alfresco, содержат заголовок Alfresco-CSRFToken и файл cookie с тем же именем. Мой сценарий содержит только Alfresco-CSRFToken в виде файла cookie и отсутствует в качестве заголовка. Я не уверен, как убедиться, что это существует как заголовок.


person vane    schedule 23.08.2015    source источник


Ответы (1)


Если вы вызываете веб-скрипты репозитория в клиентском сценарии общего доступа alfresco, вам необходимо позаботиться о следующих моментах, чтобы пройти фильтр CSRF.

Попробуйте использовать стандартный Alfresco.util.Ajax, alfresco/core/CoreXhr или Alfresco.forms.Form при отправке запроса.

Если вы не используете что-либо из вышеперечисленного, вам необходимо установить дополнительные проверки, связанные с токенами CSRF, как показано ниже.

if (Alfresco.util.CSRFPolicy && Alfresco.util.CSRFPolicy.isFilterEnabled())
{
   xhrHeadersObject[Alfresco.util.CSRFPolicy.getHeader()] = Alfresco.util.CSRFPolicy.getToken();
}

В случае источника данных YUI.

   if (Alfresco.util.CSRFPolicy && Alfresco.util.CSRFPolicy.isFilterEnabled())
{
   yuiDataSource.connMgr.initHeader(Alfresco.util.CSRFPolicy.getHeader(), Alfresco.util.CSRFPolicy.getToken(), false);
}

Используя вышеуказанные методы, вы можете избавиться от ошибок, связанных с атакой CSRF, в вашем коде.

person mitpatoliya    schedule 26.08.2015
comment
Я уже видел это, и дело в том, что все просто говорят, что это просто, просто добавьте этот фрагмент javascript... ну, ГДЕ вы добавляете этот фрагмент javascript? Я уже решил это самостоятельно, и мне потребовалось углубиться в код Alfresco, чтобы определить, что происходит, и это включает в себя создание файла javascript виджета на стороне клиента, который подключает вашу форму при загрузке для правильной отправки. - person vane; 02.09.2015
comment
Да, вам нужно создать javascript на стороне клиента, откуда вы будете вызывать веб-скрипт, и, следовательно, этот код будет внутри него. - person mitpatoliya; 02.09.2015