Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

AEM 6.1 Server Access Issue (Authenticated vs Anonymous)

Avatar

Level 3

We're in the process of upgrading from CQ 5.5 to AEM 6.1 and we're working with existing code that we have.

We've recently run into an issue on some of our upgraded servers (can't duplicate this locally on a fresh AEM 6.1) where servlets that we have configured are accessible just fine via an anonymous connection but when a user is authenticated (even on Publish which we require) then the same code acts like the Servlet doesn't exist when calling it.

I wasn't aware of any changes in AEM 6.1 that required additional changes to the code or at the OSGi Console level with regards to how a Servlet is accessed.

Here is an example of what our servlet code looks like with names removed.

@Service
@SlingServlet(paths = "/bin/abc/abc123", methods = { "POST" }, metatype = true, label = "Description of the Servlet")
public class ClassName extends SlingAllMethodsServlet {

Here is part of the jQuery Ajax request we've been using:

                $.ajax({
                    async: false,
                    type: "POST",
                    url: "/bin/abc/abc123",
                    data: { query: q},
                     dataType: "text"
                 })

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

You need to submit the CSRF token with your AJAX requests either in the request body or the header. The token is available here - http://localhost:4502/libs/granite/csrf/token.json. The token once requested times out after 10 minutes so make sure to get the token just before submitting the request. 

  1. headers: {
  2. 'CSRF-Token': token
  3. },

View solution in original post

6 Replies

Avatar

Level 10

I cannot duplicate this - i can still use AJAX to hit servlets on 6.1.

Avatar

Level 10

As this is POST request, see if you are seeing any CSRF related errors in the log. If you are seeing any errors in the log, please post the same 

Avatar

Level 3

bsloki wrote...

As this is POST request, see if you are seeing any CSRF related errors in the log. If you are seeing any errors in the log, please post the same 

 

Thanks just got a similar response from another source as well, seems this was added to AEM 6.x and our Adobe Contract folks didn't bother to tell us :)

Do you have any experience with implementing this with existing ajax calls?

Avatar

Correct answer by
Employee Advisor

You need to submit the CSRF token with your AJAX requests either in the request body or the header. The token is available here - http://localhost:4502/libs/granite/csrf/token.json. The token once requested times out after 10 minutes so make sure to get the token just before submitting the request. 

  1. headers: {
  2. 'CSRF-Token': token
  3. },

Avatar

Level 9

You also have to make changes at dispatcher level. For more details, go through below docs.

Configure Dispatcher to prevent CSRF Attacks

AEM provides a framework aimed at preventing Cross-Site Request Forgery attacks. In order to properly make use of this framework, you need to whitelist CSRF token support in the dispatcher. You can do this by:

  1. Creating a filter to allow the /libs/granite/csrf/token.json path;
  2. Creating a filter to allow the CSRF-Token header.

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

https://docs.adobe.com/docs/en/dispatcher/security-checklist.html

Jitendra

Avatar

Level 7

@Thomas_PNC @kunal123 how to get the csrf token and send while making an ajax call?

one of ajax post call is failing with "unable to read csrf meta information" and trying to get the code working.

appreciate any help. some pesudocode here:

getFundData: function(resortId, requestData) {

        var fundPromise = $.Deferred();

        $.ajax({

            type: 'POST',

            url: serviceUrl,

            data: JSON.stringify(requestData),

            dataType: 'json',

            contentType : 'application/json',

            success: function(response) {

                fundPromise.resolve(response);

            },

            error : function(errorMsg) {

                fundPromise.reject(errorMsg);

            }

        });

        return fundPromise;

    }