我正在使用自定义SMTP服务器,并希望在用户输入自己的服务器凭据时验证连接。
与添加邮件服务器时Adobe CF和Railo允许的完全相同的检查类型。
当然,这并不能保证 delivery 能够正常运行,但至少要检查输入的服务器/用户名/密码是否有效。
我可以看到一个棘手的方法:尝试使用 cfmail 发送电子邮件并检查邮件日志。但我相信它可以更优雅地完成。
是否有标准ACF / Railo发行版的Java库可以帮助我?我该如何使用它们?例子非常受欢迎。
提前致谢。
修改
请不要与Java标签混淆。 CFML 需要解决方案。虽然它可以使用一些Java库,但如果适用的话。
答案 0 :(得分:6)
我认为sfussenegger有正确的想法。但是,不是使用自定义身份验证器,而是通过connect(..)进行身份验证?仅用gmail测试过。但似乎有效。
编辑:我用CF9& OBD成功。不幸的是,我对Railo没有运气......糟糕。
编辑:已更新,以添加缺少的“mail.smtp.auth”属性。它现在应该与Railo一起正常工作。
//Java Version
int port = 587;
String host = "smtp.gmail.com";
String user = "username@gmail.com";
String pwd = "email password";
try {
Properties props = new Properties();
// required for gmail
props.put("mail.smtp.starttls.enable","true");
props.put("mail.smtp.auth", "true");
// or use getDefaultInstance instance if desired...
Session session = Session.getInstance(props, null);
Transport transport = session.getTransport("smtp");
transport.connect(host, port, user, pwd);
transport.close();
System.out.println("success");
}
catch(AuthenticationFailedException e) {
System.out.println("AuthenticationFailedException - for authentication failures");
e.printStackTrace();
}
catch(MessagingException e) {
System.out.println("for other failures");
e.printStackTrace();
}
<cfscript>
//CF Version
port = 587;
host = "smtp.gmail.com";
user = "username@gmail.com";
pwd = "email password";
try {
props = createObject("java", "java.util.Properties").init();
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
// or use getDefaultInstance instance if desired...
mailSession = createObject("java", "javax.mail.Session").getInstance(props, javacast("null", ""));
transport = mailSession.getTransport("smtp");
transport.connect(host, port, user, pwd);
transport.close();
WriteOutput("success");
}
//for authentication failures
catch(javax.mail.AuthenticationFailedException e) {
WriteOutput("Error: "& e.type &" ** "& e.message);
}
// for other failures
catch(javax.mail.MessagingException e) {
WriteOutput("Error: "& e.type &" ** "& e.message);
}
</cfscript>
答案 1 :(得分:1)
使用Apache Commons Net,您可以执行以下操作:
try {
int reply;
client.connect("mail.foobar.com");
System.out.print(client.getReplyString());
// After connection attempt, you should check the reply code to verify
// success.
reply = client.getReplyCode();
if(!SMTPReply.isPositiveCompletion(reply)) {
client.disconnect();
System.err.println("SMTP server refused connection.");
System.exit(1);
}
// Do useful stuff here.
...
} catch(IOException e) {
if(client.isConnected()) {
try {
client.disconnect();
} catch(IOException f) {
// do nothing
}
}
System.err.println("Could not connect to server.");
e.printStackTrace();
System.exit(1);
}
client
是org.apache.commons.net.smtp.SMTPClient类的实例。上面的代码取自SMTPClient API文档。
答案 2 :(得分:0)
这不是很好,但可以这样做:只需使用try发送电子邮件到非法地址,看看你得到了什么错误信息。如果错误消息抱怨身份验证失败,您就知道该怎么做了。
编辑一些有效的代码:
这是验证Gmail凭据的一些工作代码。 但Gmail不会抱怨非法的@ localhost。现在,您可以尝试搜索导致异常的收件人,或者真正将邮件发送到某个地址并立即丢弃。。编辑:甚至没有必要发送一些东西。只需连接并处理可能的AuthenticationFailedException。
import java.util.Properties;
import javax.mail.AuthenticationFailedException;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
public class Main {
private static Session createSmtpSession(final String user, final String password) {
final Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.host", "smtp.gmail.com");
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.smtp.port", "587");
props.setProperty("mail.smtp.starttls.enable", "true");
return Session.getDefaultInstance(props, new javax.mail.Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
}
});
}
private static boolean validateCredentials(String user, String password) {
try {
Transport transport = createSmtpSession(user, password).getTransport();
transport.connect();
transport.close();
} catch (AuthenticationFailedException e) {
return false;
} catch (MessagingException e) {
throw new RuntimeException("validate failed", e);
}
return true;
}
public static void main(String[] args) {
System.out.println(validateCredentials(args[0], args[1]));
}
}