CQ5: 403 Запрещается при вызове почтового сервлета

Привет! Я использую этот код для создания метода Post для моего примера приложения CQ5.

package com.adobe.cq.sling;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.rmi.ServerException;
import java.util.Dictionary;

import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.felix.scr.annotations.Reference;
import org.osgi.service.component.ComponentContext;
import javax.jcr.Session;
import javax.jcr.Node; 
import org.json.simple.JSONObject;
import java.util.UUID;

@SlingServlet(paths="/bin/mySearchServlet", methods = "POST", metatype=true)
public class HandleClaim extends org.apache.sling.api.servlets.SlingAllMethodsServlet {
     private static final long serialVersionUID = 2598426539166789515L;


     @Override
     protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServerException, IOException {

      try
      {
         //Get the submitted form data that is sent from the
              //CQ web page  
          String id = UUID.randomUUID().toString();
          String firstName = request.getParameter("firstName");
          String lastName = request.getParameter("lastName");
          String address = request.getParameter("address");
          String cat = request.getParameter("cat");
          String state = request.getParameter("state");
          String details = request.getParameter("details");
          String date = request.getParameter("date"); 
          String city = request.getParameter("city"); 

          //Encode the submitted form data to JSON
          JSONObject obj=new JSONObject();
          obj.put("id",id);
          obj.put("firstname",firstName);
          obj.put("lastname",lastName);
          obj.put("address",address);
          obj.put("cat",cat);
          obj.put("state",state);
          obj.put("details",details);
          obj.put("date",date);
          obj.put("city",city);

             //Get the JSON formatted data    
          String jsonData = obj.toJSONString();

             //Return the JSON formatted data
         response.getWriter().write(jsonData);
      }
      catch(Exception e)
      {
          e.printStackTrace();
      }
    }
}

это работает нормально с запросом GET. Но для запроса POST(doPost) я получил сообщение: 403 Forbidden, Что я должен сделать, чтобы решить эту проблему?

4 ответа

Решение

Эта проблема никогда не произойдет, если вы вызываете метод из внутреннего клиента (например: jsp-файл, ajax или сервлеты, расположенные в вашем приложении). Однако, если вы вызываете его с внешнего клиента (другой веб-сайт или плагин REST-клиента...), фильтр безопасности CQ будет активирован, чтобы предотвратить ваши действия, а затем вернет ошибку 403, чтобы удалить это, выполните следующие действия:

1 / http://localhost:4502/system/console/configMgr
2 / Поиск 'Фильтр рефералов Apache Sling'
3 / Удалить метод POST из фильтра. Затем вы можете вызвать свой метод POST где угодно.

Как уже упоминалось на http://sling.apache.org/documentation/the-sling-engine/servlets.html, сервлет, использующий sling.servlet.paths свойство может быть проигнорировано, если его путь не включен в пути выполнения (servletresolver.paths) настройки конфигурации службы SlingServletResolver. Вы должны найти эту конфигурацию в /system/console/configMgr/org.apache.sling.servlets.resolver.SlingServletResolver,

В вашем случае я предполагаю, что путь /bin/mySearchServlet не включен в этот параметр конфигурации и заставляет CQ возвращать статус 403. Если это правильно, вы можете либо добавить свой путь туда (при условии, что вы понимаете последствия для безопасности), либо смонтировать свои сервлеты по одному из путей, которые там настроены.

Обратите внимание, что лучше избегать монтирования сервлета на пути, если это возможно, создание ресурса по желаемому пути является предпочтительным, как упомянуто на этой странице документации.

В дополнение к другим ответам, если вы находитесь на AEM 6.1, эта проблема также может быть вызвана конфигурацией CSRF, как описано в этом посте.

Короткий ответ, проверьте, что метод POST НЕ находится в методах фильтра конфигурации фильтра CSRF

http://localhost:4502/system/console/configMgr/com.adobe.granite.csrf.impl.CSRFFilter

Я также использую тот же код для аналогичного набора требований, и я застрял на этой ошибке. Я решил это.

PFB шаги. Любой из них / Все может работать на вас.

  1. Однако я использовал аннотации по-другому.

    @Component (немедленное = истинное, metatype = true, метка = "Задействовать сейчас форму", description = "Задействовать сейчас форму") @Service @Properties({ @Property(name = "sling.servlet.paths", value = {"/bin/myServlet"}), @Property(name = "sling.servlet.methods", value = {"POST"}) })

  2. Я дал разрешение моему / bin / myServlet в org.apache.sling.servlets.resolver.SlingServletResolver.

  3. Использовал плакатный плагин - установите реферер в заголовке на какой-нибудь html, существующий на вашем сайте, иначе он выдаст 403 запрещенную ошибку. Также упомяните параметры для отправки и перейдите к содержимому для отправки и произнесите тело из параметров. Текстовое поле ниже должно быть заполнено. Теперь попробуйте опубликовать данные.

  4. Для специфичной для CQ части:- Я реализовал решение на основе AJAX с формами, в которые я отправляю вызов POST, используя AJAX по щелчку подтверждения. У меня также есть настраиваемое действие с forward.jsp, содержащим следующий код.

    окончательные свойства ValueMap = ResourceUtil.getValueMap(resource); String path = properties.get("customRedirectPath", ""); //path = /bin/myServlet FormsHelper.setForwardPath(slingRequest, path); FormsHelper.setRedirectToReferrer(request, true);

Мой AJAX-звонок:-

 argsObject = {
            oServiceUrl: "/bin/myServlet",
            oAjaxFormat: "html",
            oDataForAjax: $thisForm.serialize(),
            oAjaxCommMethod: "POST",
            oSuccessCallback: onSubmitSuccessCallback,
            oErrorCallback: onSubmitErrorCallback
            }

Я могу выполнить свой сервлет, как только этот вызов POST будет выполнен, и я получу действительный ответ по желанию.

Дайте мне знать, если эти шаги помогут.

Другие вопросы по тегам