代码之家  ›  专栏  ›  技术社区  ›  Sergey Galashyn

在ColdFusion中以编程方式验证邮件服务器连接

  •  6
  • Sergey Galashyn  · 技术社区  · 14 年前

    我正在使用自定义的SMTP服务器,希望在用户输入自己的服务器凭据时验证连接。

    与AdobeCF和Railo在添加邮件服务器时允许执行的检查类型完全相同。

    当然,这不能保证 传送 将正常工作,但至少要检查输入的服务器/用户名/密码是否有效。

    我可以看到一个棘手的方法:尝试用 CFmail 检查邮件日志。但我相信这可以用更优雅的方式来完成。

    有没有标准的ACF/Rayo DeXo提供的Java库来帮助我?我如何使用它们?我们非常欣赏这些例子。

    事先谢谢。

    编辑:

    请不要混淆Java标签的存在。需要的解决方案 CFML . 虽然它可以使用一些Java库,如果适用的话。

    3 回复  |  直到 10 年前
        1
  •  6
  •   Leigh josh poley    14 年前

    我认为斯福辛格的想法是正确的。但是,如果不使用自定义验证器,那么通过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>
    
        2
  •  1
  •   Kawu    10 年前

    使用 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文档。

        3
  •  0
  •   sfussenegger    14 年前

    这不是很好,但可以做到:只需使用“尝试将电子邮件发送到非法地址”,然后查看收到的错误消息。如果错误消息抱怨身份验证失败,您知道该怎么做。

    编辑一些工作代码:

    下面是一些验证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]));
        }
    
    }