簡體   English   中英

JavaMail SMTP憑據驗證,無需實際發送電子郵件

[英]JavaMail SMTP credentials verification, without actually sending an email

有沒有辦法檢查用戶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 = "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);
 }
}

由於SMTP協議本身,您遇到此問題。 身份驗證在協議中不是必需的。 當您調用方法“connect”時,您將至少執行一個返回支持的擴展的“EHLO”命令。 身份驗證是RFC中定義的擴展。 只有當服務器說它支持時,如果你提供了憑據,JavaMail才會嘗試執行“AUTH”命令。 事情是身份驗證擴展信息只有在您完成“STARTTLS”(也是一個擴展)后才能發送,因為在明確的通道上使用例如PLAIN身份驗證是不安全的。 這就是為什么JavaMail在“STARTTLS”之后執行第二次“EHLO”以更新支持的擴展。

因此,一個簡單的解決方案就是始終將“mail.smtp.starttls.enable”設置為true。 在JavaMail(至少1.4.5)中,這意味着如果服務器說它支持,則將發送“STARTTLS”命令(否則不會),然后您將獲得更新的擴展,如果需要,JavaMail可以執行“AUTH”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM