JavaMail SMTP凭据验证,而不实际发送电子邮件

4

有没有一种方法可以在不发送电子邮件或连接POP/IMAP的情况下检查用户SMTP服务器凭据。 我尝试编写的一些代码失败了。你能找到缺少什么吗?

不用担心电子邮件/密码。我知道它在那里。

注意:如果您正在尝试代码,请在提供正确凭据时通过第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 = "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 = 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);
 }
}

它运行良好。你有什么问题? - Maurice Perry
它不能正常工作。正如我所提到的,情况2/3/4应该报告某种错误,因为所做的设置不是GMail接受的设置。所以我可能需要比只有.connect()更多的东西。 具体是什么?这就是我正在努力弄清楚的。 - DarK
1个回答

2
由于SMTP协议本身的原因,您遇到了这个问题。在协议中,身份验证不是强制性的。当您调用“connect”方法时,至少会执行一个“EHLO”命令,返回支持的扩展。身份验证是在RFC中定义的一种扩展。只有在服务器支持且您已提供凭据的情况下,JavaMail才会尝试执行“AUTH”命令。问题在于,身份验证扩展信息只能在执行“STARTTLS”(这也是一种扩展)之后发送,因为在明文信道上使用PLAIN身份验证等方式是不安全的。这就是为什么JavaMail在“STARTTLS”之后执行第二个“EHLO”以更新支持的扩展。
因此,您的一个简单解决方案是始终将“mail.smtp.starttls.enable”设置为true。在JavaMail(至少是1.4.5版本)中,这意味着如果服务器支持,则会发送“STARTTLS”命令(否则不会),然后您将获得更新的扩展,并且如果需要,JavaMail可以执行“AUTH”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接