CQ5: 403 Forbidden occurs when call a Post servlet

26,921

Solution 1

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.

Solution 2

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

Solution 3

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.

Solution 4

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.

Share:
26,921

Related videos on Youtube

Tien Nguyen
Author by

Tien Nguyen

I have been on the software adventure since 2011. I love to learn and share knowledge to stackoverflow network. Email: [email protected]

Updated on May 24, 2020

Comments

  • Tien Nguyen
    Tien Nguyen about 4 years

    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 ?

  • rakhi4110
    rakhi4110 about 10 years
    /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.
  • Bertrand Delacretaz
    Bertrand Delacretaz about 10 years
    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.
  • rakhi4110
    rakhi4110 about 10 years
    I dont think POSTER plugin uses the browser cookies. This might be causing the forbidden error. Try postman - REST client for Chrome.
  • TechNiks
    TechNiks about 10 years
    @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 :)