Expand my Community achievements bar.

Weird CSFR Error on /libs/granite/csrf/token.json

Avatar

Level 3

I have the following scenario (Author Instance):

  • Install a clean AEM 6.2 or 6.3 instance (error happens on both versions)
  • Upload/install a custom (and simple) ui.app package
  • All works fine, no errors, I can create/delete pages and also access /system/console/bundles
  • Stop AEM, then restart AEM
  • Now I constantly get the error (can't create/delete pages, can't access /system/console/bundles):

02.12.2017 10:32:37.131 *ERROR* [0:0:0:0:0:0:0:1 [1512239557128] GET /libs/granite/csrf/token.json HTTP/1.1] org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable

java.lang.NoSuchMethodError: org.json.JSONWriter.<init>(Ljava/io/Writer;)V

.....

If I uninstall the package, all works fine again.

This is happening in AEM 6.2 (with or without AEM updates) AND AEM 6.3.

I am indeed using a GET servlet to retrieve content in the JSON format. And I am using jQuery for content tables on the Web pages.

A couple of interesting findings:

  • This error happens all over the place. E.g. when I load the Felix console (/system/console) the list of bundles doesn't show. Instead I get the same error message.
  • There is no cross-reference access in the whole custom package. And my servlet is a GET servlet.
  • If I enter http://localhost:4502/libs/granite/csrf/token.json I get the same error...

org.json.JSONWriter.<init>(Ljava/io/Writer;)V

Cannot serve request to /libs/granite/csrf/token.json in com.adobe.granite.csrf.impl.CSRFServlet

Exception:

java.lang.NoSuchMethodError: org.json.JSONWriter.<init>(Ljava/io/Writer;)V

at com.adobe.granite.csrf.impl.CSRFServlet.doGet(CSRFServlet.java:119)

at org.apache.sling.api.servlets.SlingSafeMethodsServlet.mayService(SlingSafeMethodsServlet.java:270)

at org.apache.sling.api.servlets.SlingSafeMethodsServlet.service(SlingSafeMethodsServlet.java:346)

at org.apache.sling.api.servlets.SlingSafeMethodsServlet.service(SlingSafeMethodsServlet.java:378)

at org.apache.sling.engine.impl.request.RequestData.service(RequestData.java:552)

To summarize:

  • After installing a custom package all works fine. But after restarting AEM, things go bologna.
  • If I uninstall the custom package (even with no restart) all works fine again and I don't get the error.
  • It's a CSRF error (cross-site...), but there are no cross site requests in the custom package.
  • If I repeat http://localhost:4502/libs/granite/csrf/token.json  after removing the custom package I get the following response.

{

token: "eyJleHAiOjE1MTIyNDE4MzUsImlhdCI6MTUxMjI0MTIzNX0.FRUNuXsR51Od_Xnhsxu7APGBKptUmJ9bha5o58-gZUA"

}

Is it possible that

  • I am missing a configuration setting somewhere? This is happening in AEM 6.2 and AEM 6.3 and I can't assume it's an "undetected bug".
  • Can't the token be generated? Or is it generated but can't be returned?

Since this is happening in both versions of AEM, 6.2 and 6.3 and since I assume I am not the only one using a GET servlet to generate a JSON response, I am quite sure I am missing some sort of configuration or setting.

Any idea what this could be?

Thanks!

The error as it appears in the error.log

02.12.2017 10:32:37.131 *ERROR* [0:0:0:0:0:0:0:1 [1512239557128] GET /libs/granite/csrf/token.json HTTP/1.1] org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable

java.lang.NoSuchMethodError: org.json.JSONWriter.<init>(Ljava/io/Writer;)V

at com.adobe.granite.csrf.impl.CSRFServlet.doGet(CSRFServlet.java:119)

at org.apache.sling.api.servlets.SlingSafeMethodsServlet.mayService(SlingSafeMethodsServlet.java:270)

at org.apache.sling.api.servlets.SlingSafeMethodsServlet.service(SlingSafeMethodsServlet.java:346)

at org.apache.sling.api.servlets.SlingSafeMethodsServlet.service(SlingSafeMethodsServlet.java:378)

at org.apache.sling.engine.impl.request.RequestData.service(RequestData.java:552)

at org.apache.sling.engine.impl.filter.SlingComponentFilterChain.render(SlingComponentFilterChain.java:44)

at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:77)

at com.day.cq.wcm.core.impl.WCMDebugFilter.doFilter(WCMDebugFilter.java:156)

at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

at com.day.cq.wcm.core.impl.WCMComponentFilter.filterRootInclude(WCMComponentFilter.java:375)

at com.day.cq.wcm.core.impl.WCMComponentFilter.doFilter(WCMComponentFilter.java:190)

at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

at com.day.cq.personalization.impl.TargetComponentFilter.doFilter(TargetComponentFilter.java:96)

.....

13 Replies

Avatar

Level 10

What code are you using in the custom package.

Also - how did you create the custom package? Are you using Maven Archetype project?

Can you do a test? Remove the app logic that encodes data as JSON and return as text - then see if the same error occurs. THis will narrow down causes.

Avatar

Level 3

I tested with another simple task, an OSGi bundle. I can upload the bundle plus a content and a dam-content package. All is fine. Then I stop AEM and restart. Now I get the same error.

What's interesting: I just uploaded an OSGi bundle. It was not used, except for the activate part. But after restarting AEM the token.json error is back

Avatar

Level 3

In the OSGi bundle I replaced org.json with GSON. After removing JSON and replacing it by GSON, and then restarting AEM 6.3, the error did not appear anymore!

In the POM I removed this dependency:

<dependency>

  <groupId>org.json</groupId>

  <artifactId>json</artifactId>

  <version>20170516</version>

</dependency>

What surprises me is that a JSON dependency can break the issuing of authentication tokens and with that the behavior of AEM. If I put the dependency back, http://localhost:4502/libs/granite/csrf/token.json will throw an error, which is appearing also when loading /system/console. If I remove that dependency and reload the OSGi bundle, http://localhost:4502/libs/granite/csrf/token.json will return a token correctly.

IMHO Adobe will want to take a closer look at the CSRF servlet and encapsulate the classes, making them independent of libraries used by custom implementations.

I will do more testing and add more findings.

Avatar

Level 3

And once again I am answering my own question...

Let me summarize:

If you add a dependency for org.json, similar to this:

<dependency>

  <groupId>org.json</groupId>

  <artifactId>json</artifactId>

  <version>20170516</version>

</dependency>

You will trigger the error

02.12.2017 10:32:37.131 *ERROR* [0:0:0:0:0:0:0:1 [1512239557128] GET /libs/granite/csrf/token.json HTTP/1.1] org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable

java.lang.NoSuchMethodError: org.json.JSONWriter.<init>(Ljava/io/Writer;)V

The consequence of this error is that a lot of features in AEM will not work anymore, from Touch UI to OSGi console (/system/console/bundle).

IMHO I would consider this a major bug in AEM 6.2 and 6.3. Adobe should either document which dependencies are "forbidden" to be used or encapsulate the packages to avoid overwrites by different versions. I suggest the latter, since with the rising of multiple different JavaScript libraries with tons of versions we will face this type of errors over and over again.

Avatar

Level 10

I suspected issue had something to do with the JSON API. This would make a good write up.

Avatar

Level 3

Yes, Apache encountered licensing issues with the standard org.json libraries and deprecated their "light JSON" implementation org.apache.commons.json. However, in this case the issue is that (according to the error message) the CSRF servlet seems to use the standard org.json libraries and if we use the same libraries, but a different version, we run into a conflict that has a huge impact on the behavior of AEM 6.2 and AEM 6.3

In my case the solution was to replace all org.json libraries with an alternative like GSON. This solved the problem.

The article you referenced also recommends alternatives, but the reason there is the deprecation of org.apache.commons.json in AEM 6.3.

Avatar

Level 3

Yes, but at the moment it seems more like defining a workaround for a major issue. Perhaps there is something I am missing like e.g. a statement somewhere saying I should not use org.json or so.

The weird thing is that removing the dependency on org.json fixed the problem. But it also fixed other Touch UI problems like components not showing in the component list or drop-downs not opening.

Maybe Adobe can take a look and share if it is indeed a bug or if there is something I am missing.

Avatar

Level 10

I will check this with the support team to see if this is a known issue.

Avatar

Level 3

Thanks, Scott and once I have their answer, we can either recommend not to use org.json or do a write-up how to use org.json properly.

Avatar

Level 10

This is good action plan - I will check with them tomorrow.

Avatar

Level 3

To summarize:

  • Don't get confused with the deprecation of the Apache Sling JSON implementation. This was due to licensing issues.
  • The org.json library is used in the CSRF servlet, and (not sure though) seems to not be wrapped.
  • You can test if you have an org.json library overload issue with http://localhost:4502/libs/granite/csrf/token.json. If you get an error message, you must be loading an incompatible org.json library. In my case this happened by using org.json dependency.
  • Best is to remove all org.json dependencies from your Maven POMs and replace with GSON or Jackson.

Avatar

Level 2

Thanks for your post!

I just encountered this kind of weird behavior using AEM 6.4! After removing the org.json in OSGI bundles, the "forbidden" issue was resolved.

I might need to search for other libraries to convert XML to Json though.