Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events
SOLVED

call third part y Rest service from aem as cloud using certificate

Avatar

Level 3

 I need to call Rest service from my Java backend , the issue is that i need to supply Certificate for the calls . i could not find any articles "how to" regarding aem as cloud

1 - where so i store the certificates on the cloud ?
https://experienceleague.adobe.com/docs/experience-manager-cloud-service/content/implementing/using-.... ?

2- can you provide example how to invoke rest call from Java beckend that use this certificate ?

3 - for developing - how to call the rest with the certificate on my local instance ? where to put the certificate ?

4 - java has lot of http client , like Jersey / Restlet does one of the is integrated into AEM already ?

1 Accepted Solution

Avatar

Correct answer by
Level 3

hi

after struggling  with this issue , i found the solution 

Solution overview:

 

  1. Extract pfx information
  2. Create system user.
  3. Map the system user.
  4. Add the certificate to this user.
  5. Create Servlet that will run under that user.

 

Prerequisites

 

  • Certificate file
  • Know the certificate keystore password (some time call passphrase)

 

 

 

Step 1 - extract key alias from certificate

 

The certificate in our case is in pfx format.

Using java “keytool” we will extract the key alias from the keystore

 

keytool -v -list -keystore cert.pfx

you will be prompt for the pfx password

value of the “alias name” , we will use it later

 

step 2

 

create system user.

Navigate to http://localhost:4502/crx/explorer/index.jsp

 

nshani1_0-1677566281938.png

 

 

Click “User Administration”

Click “login”. And give the admin credential

 

Then click “Create System User”

Give user id , in the path use  “/home/users/system

 

Don’t forget to click the green V

 

 

 

 

Click “close”

 

Step 3 -  map

 

Go to http://localhost:4502/system/console/configMgr

Find Apache Sling Service User Mapper Service Amendment

 

nshani1_2-1677566281942.png

 

 

Click on the +

 

On the service mapping you need to supply the domain (you can take it from the pom.xml )

 

Then “:” then user name and the permission needed

 

״nameoftheuserhere"=content-writer-service (in case you need to write to aem , use “content-writer-service”

 

nshani1_3-1677566281945.png

 

 

Click “Save”

 

Step 4 – add certificate to user

 

 

 

Navigate to tools->security->users

http://localhost:4502/security/users.html

 

nshani1_4-1677566281947.png

 

Find your user. “nameoftheuser”

 

Create new KeyStore and give it password (we won’t use this password now but log it)

 

nshani1_5-1677566281948.png

 

 

 

Use “Add Private Key from Keystore File” option

 

New alias – free choice , I put the user name for better clarity

Upload the pfx file in “keyStoreFile” and set the password of the pfx

 

On the “private key alias “ use the alias that you extracted before ,  and private key password use the same as keystore file password

 

nshani1_6-1677566281950.png

 

 

nshani1_7-1677566281952.png

 

 

 

 

Step 5. – running the servlet with the user

 

 

import org.apache.sling.api.SlingHttpServletRequest;

import org.apache.sling.api.SlingHttpServletResponse;

import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.api.resource.ResourceResolverFactory;

import org.apache.sling.api.servlets.SlingAllMethodsServlet;

 

 

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.Reference;

 

import javax.servlet.Servlet;

import javax.servlet.ServletException;

import java.io.IOException;

import java.util.HashMap;

 

import org.osgi.framework.Constants;

import holdings888.core.utils.HttpsClient;

 

 

@component(service = Servlet.class,

property = {

    Constants.SERVICE_DESCRIPTION + "=JSON Servlet to  api",

     "sling.servlet.paths=" + "/bin/readRules" })

 

    

  

 

public class RedirectionServlet extends SlingAllMethodsServlet {

 

    @reference

    private ResourceResolverFactory resolverFactory;

 

    private static final long serialVersionUID = 1L;

   

    @Override

    protected void doGet(final SlingHttpServletRequest req,

            final SlingHttpServletResponse resp) throws ServletException, IOException {

 

             

     

        

           

ResourceResolver resolver = null;

            HashMap<String, Object> param = new HashMap<>();

            param.put(ResourceResolverFactory.SUBSERVICE, "nameoftheuser");

 

            resolver = resolverFactory.getServiceResourceResolver(param);

       // make the call with any client implementation 

        String  res = _client.Get(http://urltoapi)

 

 

 

View solution in original post

5 Replies

Avatar

Community Advisor

You can check this java example of loading the cert from keystore and making the HTTP Get REST API call. You can try that in AEM code too.

 

https://www.javatips.net/api/uw-android-master/UWPreloader/httpcomponents-client-4.5/examples/org/ap...

 

Avatar

Level 3

thanks, this might work on my local i'll update after implementing.

 but i'm looking for a solution that will work on  aem as cloud so no local keystore 

 

thanks

Nir

Avatar

Level 3

hi 

i  have manage to make the call on my local 

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.HttpsURLConnection;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.BufferedReader;

try {
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault()
;
URL url = new URL(https://somecertsecureurl.com)_
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

String string = null;
while
((string = bufferedreader.readLine()) != null) {
   System.out.println(
"Received " + string);
}
     }
catch (IOException e) {
         e.printStackTrace()
;
    
}

 

 

java -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStore=path_to_pfx.pfx -Djavax.net.ssl.keyStorePassword="the+pfx_passphrase" -Dtrust_all_cert=true JavaDownloadFileFromURL.java

 

so  the question remain -  how to do the same on AEM as cloud ???

Avatar

Correct answer by
Level 3

hi

after struggling  with this issue , i found the solution 

Solution overview:

 

  1. Extract pfx information
  2. Create system user.
  3. Map the system user.
  4. Add the certificate to this user.
  5. Create Servlet that will run under that user.

 

Prerequisites

 

  • Certificate file
  • Know the certificate keystore password (some time call passphrase)

 

 

 

Step 1 - extract key alias from certificate

 

The certificate in our case is in pfx format.

Using java “keytool” we will extract the key alias from the keystore

 

keytool -v -list -keystore cert.pfx

you will be prompt for the pfx password

value of the “alias name” , we will use it later

 

step 2

 

create system user.

Navigate to http://localhost:4502/crx/explorer/index.jsp

 

nshani1_0-1677566281938.png

 

 

Click “User Administration”

Click “login”. And give the admin credential

 

Then click “Create System User”

Give user id , in the path use  “/home/users/system

 

Don’t forget to click the green V

 

 

 

 

Click “close”

 

Step 3 -  map

 

Go to http://localhost:4502/system/console/configMgr

Find Apache Sling Service User Mapper Service Amendment

 

nshani1_2-1677566281942.png

 

 

Click on the +

 

On the service mapping you need to supply the domain (you can take it from the pom.xml )

 

Then “:” then user name and the permission needed

 

״nameoftheuserhere"=content-writer-service (in case you need to write to aem , use “content-writer-service”

 

nshani1_3-1677566281945.png

 

 

Click “Save”

 

Step 4 – add certificate to user

 

 

 

Navigate to tools->security->users

http://localhost:4502/security/users.html

 

nshani1_4-1677566281947.png

 

Find your user. “nameoftheuser”

 

Create new KeyStore and give it password (we won’t use this password now but log it)

 

nshani1_5-1677566281948.png

 

 

 

Use “Add Private Key from Keystore File” option

 

New alias – free choice , I put the user name for better clarity

Upload the pfx file in “keyStoreFile” and set the password of the pfx

 

On the “private key alias “ use the alias that you extracted before ,  and private key password use the same as keystore file password

 

nshani1_6-1677566281950.png

 

 

nshani1_7-1677566281952.png

 

 

 

 

Step 5. – running the servlet with the user

 

 

import org.apache.sling.api.SlingHttpServletRequest;

import org.apache.sling.api.SlingHttpServletResponse;

import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.api.resource.ResourceResolverFactory;

import org.apache.sling.api.servlets.SlingAllMethodsServlet;

 

 

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.Reference;

 

import javax.servlet.Servlet;

import javax.servlet.ServletException;

import java.io.IOException;

import java.util.HashMap;

 

import org.osgi.framework.Constants;

import holdings888.core.utils.HttpsClient;

 

 

@component(service = Servlet.class,

property = {

    Constants.SERVICE_DESCRIPTION + "=JSON Servlet to  api",

     "sling.servlet.paths=" + "/bin/readRules" })

 

    

  

 

public class RedirectionServlet extends SlingAllMethodsServlet {

 

    @reference

    private ResourceResolverFactory resolverFactory;

 

    private static final long serialVersionUID = 1L;

   

    @Override

    protected void doGet(final SlingHttpServletRequest req,

            final SlingHttpServletResponse resp) throws ServletException, IOException {

 

             

     

        

           

ResourceResolver resolver = null;

            HashMap<String, Object> param = new HashMap<>();

            param.put(ResourceResolverFactory.SUBSERVICE, "nameoftheuser");

 

            resolver = resolverFactory.getServiceResourceResolver(param);

       // make the call with any client implementation 

        String  res = _client.Get(http://urltoapi)

 

 

 

Avatar

Level 1

Hey Nir,

I wanted to let you know that I came across your question about making secure HTTP calls from AEM as a Cloud. I found the problem interesting and decided to write an article addressing this issue. I'm excited to share with you that I have published an article titled Safeguarding Third-Party Integrations: Secure HTTP Calls in AEM as a Cloud.  In the article, I discuss the challenge of secure integrations, walk through the steps involved, and provide code samples for implementing the solution. I wanted to express my gratitude for inspiring me to write the article. Your question motivated me to explore this topic further and share my findings with the community. I hope the article proves helpful and valuable to you and others facing similar 

Avi Dalal