Проверка учетных данных JavaMail SMTP без фактической отправки электронной почты

Есть ли способ проверить учетные данные пользователя SMTP-сервера без отправки электронной почты или подключения к POP/IMAP. Некоторый код, который я пытался написать, терпит неудачу. Можете ли вы найти то, чего не хватает там.

Не беспокойтесь об электронной почте / пароле. Я знаю, что это там.

ПРИМЕЧАНИЕ. Если вы пробуете код. Случай 1 должен пройти при предоставлении правильных учетных данных. Если это не удается, значит, кто-то изменил пароль. Вы должны использовать другой адрес электронной почты.



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 = "[email protected]";
  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 = 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);
 }
}

person DarK    schedule 21.04.2010    source источник
comment
Это работает нормально. Какой у Вас вопрос?   -  person Maurice Perry    schedule 21.04.2010
comment
Это не работает нормально. Как я уже упоминал, случаи 2/3/4 должны сообщать о какой-то ошибке, поскольку выполненные настройки не соответствуют тем, которые принимает GMail. Так что мне, вероятно, нужно что-то большее, чем просто .connect() Что именно? Это то, что я пытаюсь понять.   -  person DarK    schedule 21.04.2010


Ответы (1)


У вас есть эта проблема из-за самого протокола SMTP. Аутентификация не является обязательной в протоколе. Когда вы вызываете метод «connect», вы выполняете как минимум команду «EHLO», которая возвращает поддерживаемые расширения. Аутентификация — это расширение, определенное в RFC. JavaMail попытается выполнить команду «AUTH» только, если сервер скажет, что поддерживает это, и если вы предоставили учетные данные. Дело в том, что информация о расширении аутентификации может быть отправлена ​​только после того, как вы выполнили «STARTTLS» (который также является расширением), потому что небезопасно использовать, например, аутентификацию PLAIN на чистом канале. Вот почему JavaMail делает второй «EHLO» после «STARTTLS» для обновления поддерживаемого расширения.

Таким образом, одно простое решение вашей проблемы — всегда устанавливать для «mail.smtp.starttls.enable» значение true. В JavaMail (по крайней мере, 1.4.5) это означает, что команда «STARTTLS» будет отправлена, если сервер скажет, что поддерживает это (в противном случае нет), тогда вы получите обновленное расширение, и JavaMail может выполнить «AUTH», если это необходимо.

person Sylvain    schedule 02.10.2012