7

Hi I'm using this code to create a Post method for my CQ5 example application.

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();
      }
    }
}

it work ok with a GET request. But for a POST(doPost) request i recevied a message: 403 Forbidden. What i should do to resolve this issue ?

Tien Nguyen
  • 4,298
  • 9
  • 30
  • 44
  • This should work perfectly. And it should throw an 405 GET not supported error when using GET request, as you havent implemented it. And for the POST it should work. Are you accessing this via a webserver? Have you checked whether the path /bin is allowed access in case you are accessing through a webserver? – rakhi4110 Apr 02 '14 at 01:44
  • Did you ever manage to solve this? I've got the exact same issue and cannot seem to figure out what the issue is – Chris Aug 27 '15 at 14:03

4 Answers4

11

This issue will never happen If you call the method from internal client (for example: jsp file, ajax or Servlets that located in your application). However if you call it from external client (another website or REST client plugin...) CQ security filter will be triggered to prevent your action then return 403 error to remove this please follow these steps:

1/ http://localhost:4502/system/console/configMgr
2/ Search for 'Apache Sling Referrer Filter'
3/ Remove POST method from the filter. Then you can call your POST method anywhere.

Tien Nguyen
  • 4,298
  • 9
  • 30
  • 44
  • I did that but somehow removing POST from referrer filters is not persisting. Every time i restart AEM, it resets and add POST in list. Any idea to fix it? – Finn Nov 26 '16 at 10:20
  • Got it, a silly miss. I checked in my config in code with POST method removed. It worked. – Finn Dec 01 '16 at 13:50
  • you just have to add between the html head tag. or use jquery from aem – Try it Mar 28 '18 at 08:11
7

As mentioned at http://sling.apache.org/documentation/the-sling-engine/servlets.html, a servlet using the sling.servlet.paths property might be ignored unless its path is included in the Execution Paths (servletresolver.paths) configuration setting of the SlingServletResolver service. You should find that configuration at /system/console/configMgr/org.apache.sling.servlets.resolver.SlingServletResolver .

In your case I suppose the /bin/mySearchServlet path is not included in that configuration parameter and causes CQ to return a 403 status. If that's right you can either add your path there (assuming you understand the security implications) or mount your servlets on one of the paths that's configured there.

Note that it's best to avoid mounting servlet on paths if possible, creating a resource at the desired path is preferred as mentioned on that documentation page.

Bertrand Delacretaz
  • 6,100
  • 19
  • 24
  • 1
    /bin/ would be available in the resolver config by default isn't it? So, it should take care of this by default. Please correct me if i am wrong. And btw, i have checked this code on my instance and it is working fine without any additional configuration. – rakhi4110 Apr 02 '14 at 09:22
  • Tien Nguyen didn't indicate if the system has a default config, so it's worth checking that. But you're right that if /bin is included in the config that I mentioned the servlet should work for POST requests. – Bertrand Delacretaz Apr 03 '14 at 09:08
7

In addition to the other answers, If you are on AEM 6.1 this issue can also be caused by a CSRF Configuration as explained on this post.

Short answer, check that the POST method is NOT in the filter methods of the CSRF filter config

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

MRodriguez08
  • 189
  • 1
  • 7
2

I am also using the same code for similar set of requirements and i was stuck on this error. I have solved it.

PFB the steps. Either of them/All might work for you as well.

  1. I have however used the annotations differently.

    @Component( immediate = true, metatype = true, label = "Engage Now Form", description = "Engage Now Form") @Service @Properties({ @Property(name = "sling.servlet.paths", value = {"/bin/myServlet"}), @Property(name = "sling.servlet.methods", value = {"POST"}) })

  2. I have given permission to my /bin/myServlet in the org.apache.sling.servlets.resolver.SlingServletResolver.

  3. Used the poster plugin - set the referer in the header to some html existing in your site heirarchy other wise it will give 403 forbidden error. Also mention the parameters to send and go to content to send and say body from parameters. The below text box shall be populated. Now try posting the data.

  4. For the CQ specific part :- i have implemented an AJAX based solution with forms where i send the POST call using AJAX on submit click. I also have a custom action in place with a forward.jsp containing the following code.

    final ValueMap properties = ResourceUtil.getValueMap(resource); String path = properties.get("customRedirectPath", ""); //path = /bin/myServlet FormsHelper.setForwardPath(slingRequest, path); FormsHelper.setRedirectToReferrer(request, true);

My AJAX call is :-

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

I am able to execute my servlet once this POST call is executed and i recieve a valid response as desired.

Let me know if these steps help.

TechNiks
  • 110
  • 9
  • I dont think POSTER plugin uses the browser cookies. This might be causing the forbidden error. Try postman - REST client for Chrome. – rakhi4110 Apr 09 '14 at 06:51
  • @rakhi4110 :- It does use the browser cookies. The problem was that i was not mentioning the referer in the header which was causing this issue. It has now been resolved. Thanks :) – TechNiks Apr 09 '14 at 16:56