简体   繁体   中英

How to call ssl endpoint fon AWS Lambda function

I have an AWS Lambda function that gets triggered by the Alexa command. On every Alexa command, I want to call an external API endpoint to do the desired operation.

I have a jar that calls the API and has the below externalService class with invokeCommand function. The jar has been added as a dependency under my Java project.

if(value.equals("something")) {
   externalService.invokeCommand();
   }

invokeCommand calls the external API which is protected by SSL certificate and throws an error

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

In Elastic Beanstalk I can create a zip folder with Jar, Keystore, and procfile and I can supply keystore as an argument in the procfile which will run the jar with the keystore and that'll allow access to SSL secured endpoint.

if(value.equals("something")) {
   externalService.invokeCommand(); // error on AWS Lambda
   }

However, I don't think I can do the same with Lambda which is not allowing me to call SSL secured endpoint.

  • Is there a way I can package my jar with the trustStore?
  • Is there a way to run a jar with command-line option in AWS Lambda just like procfile does in Elastic Beanstalk.

I believe one option would be to package the certificates into the Jar/zip for your Lambda function itself which would put them on your classpath. Once they are on your classpath you can set them up programmatically using

    System.setProperty("javax.net.ssl.keyStore", KEYSTORE_FILE);
    System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE);
    System.setProperty("javax.net.ssl.keyStoreType", "JKS");
    System.setProperty("javax.net.ssl.trustStore", TRUSTSTORE_FILE);
    System.setProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE);
    System.setProperty("javax.net.ssl.trustStoreType", "JKS");

Where you'd define KEYSTORE_FILE like

URL trustStoreResource = LdapConfig.class.getResource( "/keystore.jks" );
String KEYSTORE_FILE= trustStoreResource.toURI().getPath();
System.setProperty("javax.net.ssl.keyStore", KEYSTORE_FILE);

You have too create truststore programitically See below code for reference

        // Declare path of trust store and create file
        String trustStorePath = "/tmp/trust";
        // try creating above directory and path if you get error no such file 

        // Create Truststore using Key store api
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

        // locate the default truststore
        String filename = System.getProperty("java.home")
                + "/lib/security/cacerts".replace('/', File.separatorChar);

        try (FileInputStream fis = new FileInputStream(filename)) {

            keyStore.load(fis, "changeit".toCharArray());
        }

        // Add Certificate to Key store
        CertificateFactory certF = CertificateFactory.getInstance("X.509");
        Certificate cert = certF.generateCertificate(new FileInputStream("your certificate path"));
        keyStore.setCertificateEntry("any alias", cert);

        // Write Key Store
        try (FileOutputStream out = new FileOutputStream(trustStoreFile)) {
            keyStore.store(out, "changeit".toCharArray());
        }

        // Set Certificates to System properties
        System.setProperty("javax.net.ssl.trustStore", trustStorePath);
        System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

This you can test locally as well on aws lambda. Hope this will solve the issue

  • You can keep you certificate in s3 or keep it in resources of lambda directory

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM