JavaMail SMTP凭证验证,无需实际发送电子邮件
问题描述:
有没有办法在不发送电子邮件或连接到POP/IMAP的情况下检查用户SMTP服务器凭证。 我试图编写的一些代码在它上面失败。 你能找到那里缺少的东西吗?JavaMail 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 = "[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);
}
}
答
由于SMTP协议本身,您有此问题。协议中不强制认证。当你调用方法“connect”时,你至少会做一个“EHLO”命令来返回受支持的扩展。身份验证是在RFC中定义的扩展。如果服务器说它支持,并且您提供了凭据,则JavaMail将尝试执行“AUTH”命令而不是。事情是验证扩展信息可能只有在你完成了“STARTTLS”(也是一个扩展)之后才会发送,因为在一个空闲信道上使用例如PLAIN验证是不安全的。这就是为什么JavaMail在“STARTTLS”之后执行第二个“EHLO”以更新受支持的扩展。
因此,针对您的一个简单解决方案问题是始终将“mail.smtp.starttls.enable”设置为true。在JavaMail(至少1.4.5)中,这意味着如果服务器说它支持(否则不会),那么将发送“STARTTLS”命令,那么您将获得更新的扩展,并且如果需要,JavaMail可以执行“AUTH”。
它工作正常。你的问题是什么? – 2010-04-21 09:54:01
它不能正常工作。正如我提到2/3/4的情况下应报告某种错误,因为所做的设置不是GMail接受的设置。 所以我可能需要的东西不仅仅是.connect() 究竟是什么?那是我想要的。 – DarK 2010-04-21 12:16:12