Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

SOLVED

AEM POST service throws 401 unauthorized

Avatar

Level 2

Hi

I am trying to write a post service in aem to which i am sending data in the request body.

To read the data, i have a sling Post servlet where i am expecting to get the data sent by post via request.getReader().

To test this post servlet, i have created another servlet in the same instance which has a doGet() and the following code:

I am hitting this servlet's path in my instance to execute the following code.

CloseableHttpClient httpClient = HttpClients.createDefault();

HttpPost postRequest = new HttpPost("http://localhost:4502/bin/testingPost"); //the post servlet's path

StringEntity input = new StringEntity("<Comment>hello</Comment>");

input.setContentType("text/xml");

postRequest.setEntity(input);

HttpResponse httpResponse = httpClient.execute(postRequest);

However, i get a 401 in httpResponse while trying to access the post servlet with the path "http://localhost:4502/bin/testingPost".

I have referred a few forums where they have mentioned about removing post from Apache Sling Referer Filter and also about CSRF token but that is of no use.

And also that's not recommended as mentioned in the forums for security reasons.

ex: Apache httpclient post throws resposne status 401 Unauthorized error

However, by making the above configuration in OSGI felix console, i could do an ajax call to my post servlet which was giving me a 403 otherwise but i want to be able to hit the post servlet using the java code mentioned above.

Can you please suggest something as soon as possible.

Thank you.

1 Accepted Solution

Avatar

Correct answer by
Administrator

It is not considered as a best practice to use httpclient to send a HTTP request to AEM itself.

Because this request needs authentication. When you make httpclient call to the servlet it requires cookie object. In servlet code you will not get the cookie object, so you are getting 401 unauthorized error. If you do the GET call, you can get the cookie from request object and set the cookie attribute in httpclient.

To get this working set credentials in httpclient again not a good practice.

-Kautuk

View solution in original post

5 Replies

Avatar

Level 2

I missed out on a very important thing here actually.

For now, i am testing my post servlet by using http client code in localhost itself. But actually, there will be a third party call to the sling post servlet.

So, when i try to hit my sling post servlet via POSTMAN, i am able to get response only if i do the following:

1. Provide basic Auth (username and password) while making the call.

2. In OSGI configuartion,

     I have enabled allow empty in Apache sling referrer filter.

     In Apache Granite CSRF filter, i have removed POST.

Is there any other way possible without making the OSGI config changes (CSRF and Referrer filter)?

Avatar

Correct answer by
Administrator

It is not considered as a best practice to use httpclient to send a HTTP request to AEM itself.

Because this request needs authentication. When you make httpclient call to the servlet it requires cookie object. In servlet code you will not get the cookie object, so you are getting 401 unauthorized error. If you do the GET call, you can get the cookie from request object and set the cookie attribute in httpclient.

To get this working set credentials in httpclient again not a good practice.

-Kautuk

Avatar

Level 10

As Kautuk suggested, you need to specify the creds in the HTTP POST or remove authen for that specific servlet.

Avatar

Employee Advisor

On author authentication is required by default for every request (besides some exceptions to display the login page). The situation is different on publish instances, so you should start testing against publish instances (if that is your final usecase).

The next step are the various filters. AEM assumes by default, that users are accessing a webpage and not necessarily machines; and a browser will always send a referer header. So should your code to pass the Referer filter.

And then your code is called.

Jörg