Expand my Community achievements bar.

SOLVED

How call AEM Servlet in JSP's form tag not via Ajax

Avatar

Level 4

Hi 

We have one senario and created the drop-zone by using the dropzone.js. Now when we are trying to drop the assets in dropzone area then calling AEM servlet via form tag like:

<form method="POST" action="/bin/myServlet" class="dropzone" id="myDropzone" enctype="multipart/form-data"></form>

but getting error message like:

POST:http://localhost:4502/bin/myButtonServlet 403 forbidden

Any Idea? Are we missing anything?

Thanks

Samer

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

For ideal solution, you should include the following javascript on your page - /etc/clientlibs/granite/jquery/granite/csrf/source/csrf.js. You can include it by doing a standard client library include call in your JSP. 

<cq:includeClientLib js="granite.csrf.standalone"/>

For more details go through this- 

[1] https://docs.adobe.com/docs/en/aem/6-1/develop/security/csrf-protection.html

[2] http://blogs.adobe.com/experiencedelivers/experience-management/clientlibs-explained-example/

View solution in original post

15 Replies

Avatar

Employee Advisor

If you are on 6.1 version then I think the POST request is being blocked by the CSRF filter. And to resolve this you should include the CSRF javascript on the page which will automatically inject the CSRF token parameter in your form before submitting it.  You can confirm whether this request is blocked by CSRF or not by disabling the CSRF check on POST request temporarily - http://localhost:4502/system/console/configMgr/com.adobe.granite.csrf.impl.CSRFFilter

Check the following documentation - https://docs.adobe.com/docs/en/aem/6-1/develop/security/csrf-protection.html

Avatar

Level 9

Sameer,

It seems you are posting the data at the root node. And, The logged-in user does not have permission to add/create/update at the root node of the repository.

Is your servlet registered?.

Jitendra

Avatar

Level 4

Hi Kunal,

Yes I am using 6.1 and I just enabled the check box for CSRFFilter and tried but still getting the same error as in attachment. 

I am able to call the same servlet via AJAX but getting the error via form tag. As per our senario we need to call it on form tag because as soon as user will drop the assets in to dropzone the form tag automatically will be submitted.

Thanks

~S

Avatar

Level 4

Hi Jitendra,

Yes servlet is registered. we are not adding at root level. we are trying to to drop the assets via dropzone and calling the servlet.

 

Thanks

~S

Avatar

Employee Advisor

Do you see any errors in the error.log file when you submit the form ?

Avatar

Employee Advisor

Also,  instead of checking the checkbox in the CSRF configuration you should just remove the POST string from the Filter methods by clicking on the minus button.  

Avatar

Level 9

May I have error.log & your servlet code which returns forbidden message to the caller. By the way, When do you return forbidden response from the servlet?. Is it something on catch block?.

Jitendra

Avatar

Administrator

Hi

Please have a look at the post, it is almost synonymous to problem.

Link 1:- http://tiku.io/questions/4120715/cq5-403-forbidden-occurs-when-call-a-post-servlet

//CQ: 403 Forbidden occurs when call a Post servlet

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.

 

Link 2:- https://forums.adobe.com/thread/1120136?tstart=0

//

it is enough if you are using this kind of annotation like in your example code - maybe better is to used instead of "POST" selector some other name for it

 

@Component(immediate = true, metatype = false, label = "QuestionnaireServlet")

   @Service

   @Properties(value = {

                    @org.apache.felix.scr.annotations.Property(name = "sling.servlet.methods", value = { "POST" }),

                    @org.apache.felix.scr.annotations.Property(name = "sling.servlet.resourceTypes", value = { "sling/servlet/default" }),

                    @org.apache.felix.scr.annotations.Property(name = "sling.servlet.selectors", value = { "POST" }),

                    @org.apache.felix.scr.annotations.Property(name = "sling.servlet.extensions", value = { "html" })

   })

 

if you want to check if your servlet is registered, try to open Apache Felix Console, expand a bundle and there you should have listed your servlet as a service

 

About B

this node should not exists in the repository

Please also delete bundle form the Apache Felix Console and try to install it again and see if the servlet will be registered as a service

 

I hope this would help you.

Thanks and Regards

Kautuk Sahni    



Kautuk Sahni

Avatar

Employee

kunal23 wrote...

Also,  instead of checking the checkbox in the CSRF configuration you should just remove the POST string from the Filter methods by clicking on the minus button.  

Even for local development this shouldn't be recommended incase this config flows through to production. CSRF only comes into play for authenticated users. Is your test user logged in?

Avatar

Employee Advisor

Yes I agree. Thats why in my first answer, I suggested to remove this configuration temporarily to check whether the request is indeed blocked by CSRF or not. The ideal solution is to include the CSRF javascript on the form page which passes the token along with the form data. 

Avatar

Community Advisor
Hi Can you please check all the annotations related to the servlet and check any exception is throwing in the logs

Avatar

Level 10

Hi Samer - are you following a online doc for this. Can you point me there if so. 

Avatar

Level 4

Hi Kunal

 just remove the CSRF configuration temporarily and POST entry and checked it is working. For ideal solution do you have any sample  like to pass the token or user related information. 

Hi Opkar,

Yes, the test user logged in and trying to use the page inside AEM and trying to call the servlet

Thanks

~S

Avatar

Correct answer by
Employee Advisor

For ideal solution, you should include the following javascript on your page - /etc/clientlibs/granite/jquery/granite/csrf/source/csrf.js. You can include it by doing a standard client library include call in your JSP. 

<cq:includeClientLib js="granite.csrf.standalone"/>

For more details go through this- 

[1] https://docs.adobe.com/docs/en/aem/6-1/develop/security/csrf-protection.html

[2] http://blogs.adobe.com/experiencedelivers/experience-management/clientlibs-explained-example/

Avatar

Level 9

Check out more usefull docs...

Jitendra