javax.mail.Authenticator Example

In this post under Java Mail, I will explain the use of Authenticator abstract class with an example.

Note: For this example and other examples in future we need to have
1) Gmail account
2) GMail SMTP server address
3) Stop the antivirus software running on your local.
4) Create an application password. The steps are mentioned in the url https://support.google.com/accounts/answer/185833?p=InvalidSecondFactor

In all my examples in previous posts under Java Mail, I have hardcoded the username and password as shown below

In case of first approach


    t.connect("smtp.gmail.com","xxxxxxxxxxxxx@gmail.com", "xxxxxxxxxxxxxxxx");
    Address[] addresses = {to};
    t.sendMessage(mimeMessage, addresses);

Here you are hardcoding username and password and passing as arguments to connect method.

In case of Second Approach


    Transport.send(mimeMessage, "xxxxxxxxxx@gmail.com", "xxxxxxxxxxxxxxxx");

Here you are hardcoding username and password and passing as arguments to static send method.

In both cases we are hardcoding the username and password.

What if we want to ask user, these credentials, that’s where Authenticator class will help us.

Authenticator is an abstract class so we have to create a custom class say ‘CustomAuthenticator’ extending Authenticator class. An instance of this ‘CustomAuthenticator’ has to registered with the session, when the session is being created as shown below


    CustomAuthenticator customAuthenticator = new CustomAuthenticator();
    Session session = Session.getInstance(properties, customAuthenticator);

Below is the class structure of ‘CustomAuthenticator’

CustomAuthenticator


1  package package5;
2  
3  import java.util.Scanner;
4  
5  import javax.mail.Authenticator;
6  import javax.mail.PasswordAuthentication;
7  
8  public class CustomAuthenticator extends Authenticator {
9      @Override
10     protected PasswordAuthentication getPasswordAuthentication() {
11         Scanner scanner = new Scanner(System.in);
12         System.out.println("Enter the username");
13         String userName = scanner.nextLine();
14         System.out.println("Enter the password");
15         String password = scanner.nextLine();
16         PasswordAuthentication passwordAuthentication = new PasswordAuthentication(userName, password);
17         scanner.close();
18         return passwordAuthentication;
19     }
20 }

The important method in the Authenticator class that we need to focus on is ‘getPasswordAuthentication()’ method as shown in the above CustomAuthenticator class.
I have overridden the ‘getPasswordAuthentication’ method. This method asks the user through command line interface the username and password. Using the information provided by the user we create a PasswordAuthentication object and return it. We don’t need to specifically call this method, as this method is called by specific protocol implementation automatically.

In this way we can ask the user the credentials required to login in to their email account.

Below is the code that shows how to use ‘CustomAuthenticator’ using approach 1

Approach 1


1  package package24;
2  
3  import java.util.Properties;
4  
5  import javax.mail.Address;
6  import javax.mail.Message;
7  import javax.mail.MessagingException;
8  import javax.mail.Session;
9  import javax.mail.Transport;
10 import javax.mail.internet.InternetAddress;
11 import javax.mail.internet.MimeMessage;
12 
13 public class Example24 {
14     public static void main(String[] args) {
15         Properties properties = new Properties();
16         properties.put("mail.smtp.host", "smtp.gmail.com");
17         properties.put("mail.smtp.ssl.enable", "true");
18         properties.put("mail.smtp.auth", "true");
19         CustomAuthenticator customAuthenticator = new CustomAuthenticator();
20         Session session = Session.getInstance(properties, customAuthenticator);
21         session.setDebug(true);
22         MimeMessage mimeMessage = new MimeMessage(session);
23         
24         Transport t = null;
25         try {
26             t = session.getTransport("smtp");
27             Address from = new InternetAddress("sumanth.prabhakar@gmail.com");
28             Address to = new InternetAddress("ksprao16@gmail.com");
29             
30             mimeMessage.setText("Welcome to email");
31             mimeMessage.setSubject("Welcome");
32             mimeMessage.setFrom(from);
33             mimeMessage.setRecipient(Message.RecipientType.TO, to);
34             
35             t.connect();
36             Address[] addresses = {to};
37             t.sendMessage(mimeMessage, addresses);
38         } catch(MessagingException excep) {
39             excep.printStackTrace();
40         } finally {
41             if(t != null) {
42                 try {
43                     t.close();
44                 } catch(MessagingException excep) {
45                     excep.printStackTrace();
46                 }
47             }
48         }
49     }
50 }

In the approach 1 we used to pass the credentials as arguments to connect method. But here at line 35 we are calling connect method without any arguments. We need to use ‘smtp’ protocol instead of ‘smtps’ protocol. We also need to provide values for Java Mail System properties such as ‘mail.smtp.host’, ‘mail.smtp.ssl.enable’, and ‘mail.smtp.auth’ in the Properties object created at line 15. Remaining else is same.

Below is the code that shows how to use ‘CustomAuthenticator’ using approach 2

Approach 2


1  package package5;
2  
3  import java.util.Properties;
4  
5  import javax.mail.Address;
6  import javax.mail.Message;
7  import javax.mail.MessagingException;
8  import javax.mail.Session;
9  import javax.mail.Transport;
10 import javax.mail.internet.InternetAddress;
11 import javax.mail.internet.MimeMessage;
12 
13 public class Example5 {
14     public static void main(String[] args) {
15         Properties properties = new Properties();
16         properties.put("mail.smtp.host", "smtp.gmail.com");
17         properties.put("mail.smtp.ssl.enable", "true");
18         properties.put("mail.smtp.auth", "true");
19         CustomAuthenticator customAuthenticator = new CustomAuthenticator();
20         Session session = Session.getInstance(properties, customAuthenticator);
21         session.setDebug(true);
22         MimeMessage mimeMessage = new MimeMessage(session);
23         
24         try {
25             Address from = new InternetAddress("sumanth.prabhakar@gmail.com");
26             Address to = new InternetAddress("ksprao16@gmail.com");
27             
28             mimeMessage.setText("Welcome to email");
29             mimeMessage.setSubject("Welcome");
30             mimeMessage.setFrom(from);
31             mimeMessage.setRecipient(Message.RecipientType.TO, to);
32             
33             Transport.send(mimeMessage);
34         } catch(MessagingException excep) {
35             excep.printStackTrace();
36         }
37     }
38 }

In the approach 2, we just added another Java Mail System property called ‘mail.smtp.auth’ in Properties instance created at line 15 and set it to true. We are calling an overloaded version of send method which only takes the message as argument.

Leave a Reply