Expand my Community achievements bar.

author 401 error

Avatar

Level 4

Below is my code to servlet

package com.***.core.servlets;

@Component(service = { Servlet.class })
@SlingServletResourceTypes(resourceTypes = "dcp/servlet/assets-locked", methods = HttpConstants.METHOD_GET, extensions = "json")
public class DCPLockedAssetsRequestServlet extends SlingSafeMethodsServlet {
       @Override
   protected void doGet(SlingHttpServletRequest requestSlingHttpServletResponse responsethrows IOException {
        response.setContentType("application/json");
        LOG.info("Forwarding POST request to author instance with Basic Authentication.");
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // Adapt session and validate user
        Session session = request.getResourceResolver().adaptTo(Session.class);
        String userId = session.getUserID();   
        UserManager userManager = request.getResourceResolver().adaptTo(UserManager.class);
        Map<StringStringpayloadMap = new HashMap<StringString>();
            currentUser = userManager.getAuthorizable(userId);            
            payloadMap.put("assetsPath", assetPath);
            payloadMap.put("userId", userId);
            payloadMap.put("userPath"currentUser.getPath().toString());
            payloadMap.put("principalName"currentUser.getPrincipal().getName());             
        String authorServiceURL = techCredentialService.getAuthorServletURL();
        // Prepare HTTP POST request to author
        HttpPost postRequest = new HttpPost(authorServiceURL);
            token = dcpUpdateUserService.getToken();
            postRequest.setHeader("Authorization", "Bearer " + token);
        postRequest.setHeader(***Constants.CONTENT_TYPE, ***Constants.CONTENT_TYPE_JSON);        
        postRequest.setEntity(new StringEntity(new Gson().toJson(payloadMap)));
       
        // Execute the HTTP request
        org.apache.http.HttpResponse authorResponse = httpClient.execute(postRequest);       
        if (statusCode == 200) {
            String responseContent = EntityUtils.toString(authorResponse.getEntity());
            JsonObject jsonResponse = new JsonObject();
            jsonResponse.addProperty(***Constants.STATUS, "success");
            jsonResponse.addProperty(***Constants.MESSAGE, "Workflow triggered successfully.");
            response.getWriter().write(jsonResponse.toString());
         }}

i am hitting this servlet from publisher,
through this servlet when i hit the author path i.e 
https://author-***-***.adobeaemcloud.com/content/api/***/2025.4/locked-assets-author.json

it gives us 401 unauthorised from author

we have used the tech credentials of the techaccount user, through that we are getting access token and providing to it and we have given all the permission to that useron root jcr:All, but its giving 401 then also

Please, ASAP can i get the help??
8 Replies

Avatar

Community Advisor

Hi,

 

Clearly, the issue lies with the token. Please debug and validate that the Authorization header is correctly formed, and confirm that the token you're using is valid. You can try hitting the author instance using the token via Postman or another tool to ensure it’s working properly.

 

Please check this example: https://experienceleague.adobe.com/en/docs/experience-manager-learn/getting-started-with-aem-headles...

 

Hope this helps!



Esteban Bustamante

Avatar

Level 4

Hi @EstebanBustamante ,

I tested it using the PostMan and standalone Main Program and it looks to be working fine. But when hitting with publisher its getting 401 and when having token in the logs we copied it and through that token only we hit the servlet throygh postman, it worked but don't know what the problem when calling it through this code through publisher??

Avatar

Community Advisor

Is this working locally?



Esteban Bustamante

Avatar

Community Advisor

Hi @bhavigoyal , 

401 unauthorised error suggest token is expired or not valid(malformed/null).

Either debug or just log the value of token after statement token = dcpUpdateUserService.getToken();

Just make sure in general token have expiration time so hopefully service would be either generating token each time or would be regenerating before token get expired.

Thanks

Avatar

Level 9

Hi @bhavigoyal,

I don't see anything wrong with your code example. Sometimes when facing such weird issues it is best to try another option and compare the results.

If you have checked all the other options my colleagues suggested, then I suggest you try using a simple POST request to the OTTB POST Servlet. If that is working fine then you can compare the two requests and check what is difference. If it's not working, then we can conclude the issue is not with your code but somewhere on the network/firewall level.

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.UrlEncodedFormEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import javax.servlet.Servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Component(
    service = Servlet.class,
    property = {
        "sling.servlet.paths=/bin/example/updateComponent",
        "sling.servlet.methods=GET"
    }
)
public class UpdateComponentPropertyServlet extends SlingAllMethodsServlet {

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
        // Path to the component on the Author instance
        String componentPath = "/content/my-site/en/jcr:content/my-component";
        String authorUrl = "https://author.example.com" + componentPath;

        // Authorization token (use a secure mechanism to retrieve this)
        String authorizationToken = "Bearer YOUR_TOKEN_HERE";

        // HTTP client
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost postRequest = new HttpPost(authorUrl);

            // Set headers
            postRequest.setHeader("Authorization", authorizationToken);
            postRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");

            // Set parameters for the Sling POST servlet
            List<BasicNameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("./myProperty", "newValue")); // Update "myProperty" to "newValue"
            params.add(new BasicNameValuePair(":operation", "modify"));    // Required operation for the POST servlet
            postRequest.setEntity(new UrlEncodedFormEntity(params));

            // Execute request
            httpClient.execute(postRequest);
            response.getWriter().write("Component property updated successfully.");
        } catch (Exception e) {
            response.getWriter().write("Failed to update component property: " + e.getMessage());
        }
    }
}

 

In the lack of a better advice, I hope this helps,

Daniel