开发者

JavaMail SMTP credentials verification, without actually sending an email

Is there a way to check user SMTP server credentials without sending email, or connecting to POP/IMAP. Some code I tried to write, fails at it. Can you find what is missing there.

Don't worry about Email / password. I know it's there.

NOTE : If you are trying out the code. The case 1 should pass when supplying the correct credentials. If it fails, then someone changed the password. You should use some other email address.



import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;

public class EmailTest {

 public static void main(String[] args) {
  EmailHelper eh = new EmailHelper();

  /* GMail Setting for SMTP using STARTTLS */
  String name = "AAA";
  String email = "mymasterpainter@gmail.com";
  String smtpHost = "smtp.gmail.com";
  String serverPort = "587";
  String requireAuth = "true";
  String dontuseAuth = "false";
  String userName = email; // same as username for GMAIL
  String password = "zaq12wsx";
  String incorrectPassword = "someRandomPassword";
  String enableSTARTTLS = "true";
  String dontenableSTARTTLS = "false";

  try {
   /* only valid case */
   eh.sendMail(name, email, smtpHost, serverPort, requireAuth,
     userName, password, enableSTARTTLS);
   System.out.println("Case 1 Passed");

   /* should fail since starttls is required for GMAIL. */
   eh.sendMail(name, email, smtpHost, serverPort, requireAuth,
     userName, password, dontenableSTARTTLS);
   System.out.println("Case 2 Passed");

   /* should fail since GMAIL requires authentication */
   eh.sendMail(name, email, smtpHost, serverPort, dontuseAuth, "", "",
     dontenableSTARTTLS);
   System.out.println("Case 3 Passed");

   /* should fail. password is incorrect and starttls is not enabled */
   eh.sendMail(name, email, smtpHost, serverPort, requireAuth,
     userName, incorrectPassword, dontenableSTARTTLS);
   System.out.println("Case 4 Passed");
  } catch (MessagingException e) {
   e.printStackTrace();
  }
 }

}

class EmailHelper {

 private Properties properties = null;
 private Authenticator authenticator = null;
 private Session session = null;

 public void sendMail(String name, String email, String smtpHost,
   String serverPort, String requireAuth, String userName,
   String password, String enableSTARTTLS) throws MessagingException {
  properties = System.getProperties();
  properties.put("mail.smtp.host", smtpHost);
  properties.put("mail.smtp.port", serverPort);
  properties.put("mail.smtp.starttls.enable", enableSTARTTLS);
  properties.put("mail.smtp.auth", requireAuth);
  properties.put("mail.smtp.timeout", 20000);

  authenticator 开发者_StackOverflow= new SMTPAuthenticator(userName, password);

  session = Session.getInstance(properties, authenticator);

  // session.setDebug(true);

  Transport tr = session.getTransport("smtp");
  tr.connect();
  /*
   * do I need more than just connect? Since when i try to send email with
   * incorrect credentials it fails to do so. But I want to check
   * credentials without sending an email. Assume that POP3/IMAP username
   * is not same as the SMTP username, since that might be one of the
   * cases
   */
 }
}

class SMTPAuthenticator extends Authenticator {

 private String userName = null;
 private String password = null;

 public SMTPAuthenticator(String userName, String password) {
  this.userName = userName;
  this.password = password;

 }

 @Override
 public PasswordAuthentication getPasswordAuthentication() {
  return new PasswordAuthentication(userName, password);
 }
}


You have this problem because of the SMTP protocol itself. The authentication is not mandatory in the protocol. When you call the method "connect" you will do at least an "EHLO" command which returns supported extensions. Authentication is an extension defined in a RFC. JavaMail will try to do an "AUTH" command only if the server says it supports so and if you have provided the credentials. The things is the Authentication extension information may be sent only after you've done a "STARTTLS" (which is also an extension) because it's not safe to use for example PLAIN authentication on a clear channel. That's why JavaMail does a second "EHLO" after a "STARTTLS" to update supported extension.

So one simple solution for you problem is to always put "mail.smtp.starttls.enable" to true. In JavaMail (1.4.5 at least), this means "STARTTLS" command will be sent if the server says it supports so (otherwise not) then you will get the updated extension and JavaMail may do an "AUTH" if needed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜