Home > other >  I have been trying to implement a secure transmission of emailing using smtp protocol in AWS Lambda
I have been trying to implement a secure transmission of emailing using smtp protocol in AWS Lambda

Time:02-27

It's a Spring Boot Java Lambda for secure smtp mail transmission and it does not work while it does work in another api code of Spring Boot. Whenever I run this code it gives either SecurityException on one occassion or AuthenticationException on another and when I use getDefaultInstance() method of Session instead of getInstance() it gives "cannot create a default session". It does not even creates an object for Authenticator and gives Authentication Exception on Lambda.

---code below--

import java.util.Properties;

import javax.mail.PasswordAuthentication;
import javax.mail.Session;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
public class EmailConfig {
    
    private String username = "";
    private String password = "";
    @Bean
    public Session getEmailSession(Environment env) {
        Properties props = System.getProperties();
        props.setProperty("mail.smtp.host", "smtp.gmail.com");
        props.setProperty("mail.smtp.port", "587");
        props.setProperty("mail.smtp.auth", "true");
        props.setProperty("mail.smtp.starttls.enable", "true");
        
        Session session = Session.getInstance(props,
                new javax.mail.Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password); // username & password coming from vault
                    }
                });
        return session;
    }
}

CodePudding user response:

Look at using the Amazon Simple Email Service if you need email functionality from either an AWS Lambda function or even a Spring Boot app. There are no issues when doing so. You can easily send an email message using this SES Java Code:

// snippet-start:[ses.java2.sendmessage.request.import]
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ses.SesClient;
import software.amazon.awssdk.services.ses.model.*;
import software.amazon.awssdk.services.ses.model.Message;
import software.amazon.awssdk.services.ses.model.Body;
import javax.mail.MessagingException;
// snippet-end:[ses.java2.sendmessage.request.import]

/**
 * To run this Java V2 code example, ensure that you have setup your development environment, including your credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class SendMessageEmailRequest {

    public static void main(String[] args) {

        final String USAGE = "\n"  
                "Usage:\n"  
                "    SendMessage <sender> <recipient> <subject> \n\n"  
                "Where:\n"  
                "    sender - an email address that represents the sender. \n" 
                "    recipient -  an email address that represents the recipient. \n" 
                "    subject - the  subject line. \n" ;

          if (args.length != 3) {
            System.out.println(USAGE);
             System.exit(1);
           }

        String sender = args[0];
        String recipient = args[1];
        String subject = args[2];

        Region region = Region.US_EAST_1;
        SesClient client = SesClient.builder()
                .region(region)
                .build();

        // The email body for non-HTML email clients
        String bodyText = "Hello,\r\n"   "See the list of customers. ";

        // The HTML body of the email
        String bodyHTML = "<html>"   "<head></head>"   "<body>"   "<h1>Hello!</h1>"
                  "<p> See the list of customers.</p>"   "</body>"   "</html>";

        try {
            send(client, sender, recipient, subject, bodyText, bodyHTML);
            client.close();
            System.out.println("Done");

        } catch (MessagingException e) {
            e.getStackTrace();
        }
    }

    // snippet-start:[ses.java2.sendmessage.request.main]
    public static void send(SesClient client,
                            String sender,
                            String recipient,
                            String subject,
                            String bodyText,
                            String bodyHTML
    ) throws MessagingException {

        Destination destination = Destination.builder()
                .toAddresses(recipient)
                .build();

        Content content = Content.builder()
                .data(bodyHTML)
                .build();

        Content sub = Content.builder()
                .data(subject)
                .build();

        Body body = Body.builder()
                .html(content)
                .build();

        Message msg = Message.builder()
                .subject(sub)
                .body(body)
                .build();

        SendEmailRequest emailRequest = SendEmailRequest.builder()
                .destination(destination)
                .message(msg)
                .source(sender)
                .build();

        try {
            System.out.println("Attempting to send an email through Amazon SES "   "using the AWS SDK for Java...");
            client.sendEmail(emailRequest);

        } catch (SesException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        // snippet-end:[ses.java2.sendmessage.request.main]
    }
}

CodePudding user response:

It's Throwing error in Lambda : 2022-02-27T04:49:42.216 05:30

Copy software/amazon/awssdk/regions/Region: java.lang.NoClassDefFoundError java.lang.NoClassDefFoundError: software/amazon/awssdk/regions/Region at aws.smtp.lambda.demo.SendMessageEmailRequest.main_meth(SendMessageEmailRequest.java:47) at aws.smtp.lambda.demo.LambdaFunctionHandler.handleRequest(LambdaFunctionHandler.java:42) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) Caused by: java.lang.ClassNotFoundException: software.amazon.awssdk.regions.Region. Current classpath: file:/var/task/

software/amazon/awssdk/regions/Region: java.lang.NoClassDefFoundError java.lang.NoClassDefFoundError: software/amazon/awssdk/regions/Region at aws.smtp.lambda.demo.SendMessageEmailRequest.main_meth(SendMessageEmailRequest.java:47) at aws.smtp.lambda.demo.LambdaFunctionHandler.handleRequest(LambdaFunctionHandler.java:42) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) Caused by: java.lang.ClassNotFoundException: software.amazon.awssdk.regions.Region. Current classpath: file:/var/task/

Code below :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>aws.smtp.lambda</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot Lambda smtp</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bundle</artifactId>
            <version>2.9.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

    <!--    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>-->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!-- <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-tests</artifactId>
            <version>1.0.0</version>
            <scope>test</scope>
        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-ses -->
        <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-ses</artifactId> 
            <version>1.9.16</version> </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-ses</artifactId>
            <version>1.11.561</version>
        </dependency>
        <!-- Thanks for using https://jar-download.com -->

    </dependencies>

    <!-- <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <configuration>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build> -->

</project>
package aws.smtp.lambda.demo;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.amazonaws.services.lambda.runtime.Context;
//import com.amazonaws.services.lambda.runtime.RequestHandler;
//import com.amazonaws.services.lambda.runtime.events.ScheduledEvent;

@SpringBootApplication
public class LambdaFunctionHandler /*implements RequestHandler<ScheduledEvent, String>*/ {

    //private Context applicationContext;
//  @Autowired
    private SendMessageEmailRequest reqSES = new SendMessageEmailRequest();
    
    /*@Autowired
    private AmazonSESSample sesSample = new AmazonSESSample();*/
    /*@Autowired
    private SimpleEmail simpleEmail = new SimpleEmail();
    */
    public LambdaFunctionHandler() {
        
    }
/*  public LambdaFunctionHandler(Context context) {
        applicationContext = context;
    }*/

    /*public void initialize() {
        applicationContext = new SpringApplicationBuilder(LambdaFunctionHandler.class).web(WebApplicationType.NONE)
                .run();
    }*/

    public String handleRequest(/*ScheduledEvent input,*/ Context context) throws Exception {
    /*  try {
            if(Objects.isNull(applicationContext)) {
                initialize();
            }*/
            context.getLogger().log("Input: " );
//          simpleEmail.sendMail();
//          sesSample.sendMail();
            System.out.println("Going Inside SES Class ");
            reqSES.main_meth();
            return "Hello World - " ;//  input;
        /*}
        catch(Exception ex) {
            ex.printStackTrace();
            return "Failure";
        }*/
    }
    
    public static void main(String args[]) {
        
    }
}
package aws.smtp.lambda.demo;

import javax.mail.MessagingException;

//snippet-end:[ses.java2.sendmessage.request.import]
import org.springframework.stereotype.Service;

//snippet-start:[ses.java2.sendmessage.request.import]
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ses.SesClient;
import software.amazon.awssdk.services.ses.model.Body;
import software.amazon.awssdk.services.ses.model.Content;
import software.amazon.awssdk.services.ses.model.Destination;
import software.amazon.awssdk.services.ses.model.Message;
import software.amazon.awssdk.services.ses.model.SendEmailRequest;
//import software.amazon.awssdk.services.ses.model.SesException;

/**
* To run this Java V2 code example, ensure that you have setup your development environment, including your credentials.
*
* For information, see this documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
*/
@Service
public class SendMessageEmailRequest {

 public void main_meth(/*String[] args*/) {
     System.out.println(" Inside SES Class : main_meth");
     final String USAGE = "\n"  
             "Usage:\n"  
             "    SendMessage <sender> <recipient> <subject> \n\n"  
             "Where:\n"  
             "    sender - an email address that represents the sender. \n" 
             "    recipient -  an email address that represents the recipient. \n" 
             "    subject - the  subject line. \n" ;
     System.out.println("Inside SES Class ");
      /* if (args.length != 3) {
         System.out.println(USAGE);
          System.exit(1);
        }*/

     String sender = ""; // written correctly in the original code 
     String recipient = ""; // written correctly in the original code 
     String subject = "Amazon SES test (AWS SDK for Java)";

     Region region = Region.AP_SOUTH_1; // failing in this line
     /*SesClient client = SesClient.builder()
             .region(region)
             .build();*/
     
     // The email body for non-HTML email clients
     String bodyText = "Hello,\r\n"   "See the list of customers. ";

     // The HTML body of the email
     String bodyHTML = "<html>"   "<head></head>"   "<body>"   "<h1>Hello!</h1>"
               "<p> See the list of customers.</p>"   "</body>"   "</html>";

     try {
         System.out.println(" Inside SES Class : main_meth : in try block");
        // send(client, sender, recipient, subject, bodyText, bodyHTML);
         //client.close();
         System.out.println("Done");

     } catch (/*Messaging*/Exception e) {
         e.getStackTrace();
     }
 }

 // snippet-start:[ses.java2.sendmessage.request.main]
 /*public void send(SesClient client,
                         String sender,
                         String recipient,
                         String subject,
                         String bodyText,
                         String bodyHTML
 ) throws MessagingException {

     Destination destination = Destination.builder()
             .toAddresses(recipient)
             .build();

     Content content = Content.builder()
             .data(bodyHTML)
             .build();

     Content sub = Content.builder()
             .data(subject)
             .build();

     Body body = Body.builder()
             .html(content)
             .build();

     Message msg = Message.builder()
             .subject(sub)
             .body(body)
             .build();

     SendEmailRequest emailRequest = SendEmailRequest.builder()
             .destination(destination)
             .message(msg)
             .source(sender)
             .build();

     try {
         System.out.println("Attempting to send an email through Amazon SES "   "using the AWS SDK for Java...");
         client.sendEmail(emailRequest);

     } catch (SesException e) {
         System.err.println(e.awsErrorDetails().errorMessage());
         System.exit(1);
     }
     // snippet-end:[ses.java2.sendmessage.request.main]
 }*/
}
  • Related