Expand my Community achievements bar.

Submissions are now open for the 2026 Adobe Experience Maker Awards.

Persistent Query Execution Works fine in Local Instance Programmatically but not on AEM dev instance

Avatar

Level 2

Hi,

I have created below method to execute the graphql query , It works fine on the local but on the dev server it's not working due to unauthorized, I tried to create using service user but that also not working . Does anyone excuted graphql query using basic authentication or any other approach in AEM 6.5

HttpPost httpPost = new HttpPost(GRAPHQL_ENDPOINT);
httpPost.setHeader("Content-Type", "application/json");

RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.build();

try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build()) {
String username = "admin";
String password = "admin";
String auth = username + ":" + password;
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());
httpPost.setHeader("Authorization", "Basic " + encodedAuth);

StringEntity requestEntity = new StringEntity("{\"variables\":" + variables + "}");
httpPost.setEntity(requestEntity);

try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
int statusCode = httpResponse.getStatusLine().getStatusCode();
logger.debug("HTTP Response Status Code: {}", statusCode);

if (statusCode == 200) {
HttpEntity responseEntity = httpResponse.getEntity();
String jsonResponse = EntityUtils.toString(responseEntity);
3 Replies

Avatar

Level 10

hi @lax50

GraphQL on AEM 6.5 can be authenticated, but on Publish instances the recommended and most reliable pattern is to execute persisted queries with proper Dispatcher, CORS, and permissions, which differ from local and commonly cause 401 on Dev/Publish. Local POST queries often fail in Dev due to Dispatcher rules, missing replication, and stricter CORS/Referrer settings, so aligning with the persisted-query approach resolves most unauthorized errors

 

What to do:

  • Use persisted queries on Publish at /graphql/execute.json/<config>/<name> and allow/cache them at Dispatcher/CDN.

  • Protect sensitive content with CUGs and authenticate only when accessing those folders; keep public data anonymous for better caching.

You can find more info on the topic in:

Avatar

Level 3

Hi @lax50,

The issue isn’t with your HTTP client code (that works fine locally), but with authentication on your Dev environment.

In AEM 6.5, calling the GraphQL endpoint directly requires a valid, authorised user. Using admin: admin won’t work on non-local environments because:

  • Admin access is usually disabled in higher environments.

  • Basic authentication may be blocked depending on your setup (Dispatcher, SAML/SSO, IMS integration, etc.).

  • Recommended Approaches

    1. Service User / System User

      • Create a system user (via CRX Explorer or RepoInit script).

      • Give it the necessary permissions (read access under /content and /conf where GraphQL models live).

      • Use a ResourceResolver with this service user to call the GraphQL query inside AEM (instead of external HTTP Basic Auth).

      Example:

       
      @reference private ResourceResolverFactory resolverFactory; Map<String, Object> authInfo = Collections.singletonMap( ResourceResolverFactory.SUBSERVICE, "my-service-user" ); try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(authInfo)) { GraphqlClient client = resolver.adaptTo(GraphqlClient.class); GraphqlResponse response = client.execute("{ yourQueryHere }"); }

      👉 This way, you don’t need Basic Auth, and it works consistently across environments.

Avatar

Level 2

Hi @Syed_Shaik .

I was trying the same thing yesterday but somehow  GraphqlClient and GraphqlResponse dependency is not resolved in compile time itself
I added below depenedncy in my main pom  

do you have any idea which one dependency to need to add 

<dependency>
<groupId>com.adobe.aem.headless</groupId>
<artifactId>aem-headless-client-java</artifactId>
<version>1.1.0</version> <!-- Use the latest version available -->
<scope>provided</scope>
</dependency>