将JavaMail与TLS结合使用

dan*_*aro 46 java ssl smtp jakarta-mail

我在SO上发现了关于JavaMail API和通过SMTP服务器发送邮件的其他几个问题,但没有人讨论过使用TLS安全性.我正在尝试使用JavaMail通过我的工作SMTP邮件服务器向我自己发送状态更新,但它需要TLS,我无法在线找到有关如何使用JavaMail访问需要TLS加密的SMTP服务器的任何示例.有人能帮忙吗?

Sar*_*rat 62

我们的产品实际上有一些通知代码,如果有可用的话,它会使用TLS发送邮件.

您需要设置Java Mail属性.您只需要TLS,但如果您的SMTP服务器使用SSL,则可能需要SSL.

Properties props = new Properties();
props.put("mail.smtp.starttls.enable","true");
props.put("mail.smtp.auth", "true");  // If you need to authenticate
// Use the following if you need SSL
props.put("mail.smtp.socketFactory.port", d_port);
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
Run Code Online (Sandbox Code Playgroud)

然后,您可以将其传递给JavaMail会话或任何其他会话实例化器Session.getDefaultInstance(props).

  • 请注意,现代java.mail不需要设置套接字工厂:http://stackoverflow.com/questions/17581066/using-javamail-with-a-self-signed-certificate/17584714#17584714 (3认同)
  • 非常感谢!我所做的就是添加一行props.put("mail.smtp.starttls.enable","true"); 我的代码,它完美地工作! (2认同)

小智 25

好帖子,行

props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
Run Code Online (Sandbox Code Playgroud)

如果SMTP服务器使用SSL身份验证,则必须使用,例如GMail SMTP服务器.但是,如果服务器使用TLS上的纯文本身份验证,则它不应该存在,因为Java Mail会抱怨初始连接是纯文本.

还要确保使用的是最新版本的Java Mail.最近我使用了之前项目中的一些旧Java Mail jar并且无法使代码工作,因为登录过程失败了.在我升级到最新版本的Java Mail后,错误的原因变得清晰:它是一个javax.net.ssl.SSLHandshakeException,它没有在旧版本的lib中引发.


Bre*_*lle 8

上面示例中的设置不适用于我使用的服务器(authsmtp.com).我一直收到这个错误:

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
Run Code Online (Sandbox Code Playgroud)

我删除了mail.smtp.socketFactory设置,一切正常.最终设置是这样的(没有使用SMTP身份验证,我在其他地方设置了端口):

java.util.Properties props = new java.util.Properties();
props.put("mail.smtp.starttls.enable", "true");
Run Code Online (Sandbox Code Playgroud)


Ren*_*unt 6

只需使用以下代码即可.通过Java发送电子邮件非常有用,它可以工作:

import java.util.*;
import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.*;
import javax.mail.Provider;
import javax.mail.internet.*;

public class Main {

    public static void main(String[] args) {
            final String username="your@gmail.com";
            final String password="password";
            Properties prop=new Properties();
            prop.put("mail.smtp.auth", "true");
            prop.put("mail.smtp.host", "smtp.gmail.com");
            prop.put("mail.smtp.port", "587");
            prop.put("mail.smtp.starttls.enable", "true");

            Session session = Session.getDefaultInstance(prop,
          new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
          }
        });
          try {
                 String body="Dear Renish Khunt Welcome";
                 String htmlBody = "<strong>This is an HTML Message</strong>";
                 String textBody = "This is a Text Message.";
         Message message = new MimeMessage(session);
         message.setFrom(new InternetAddress("your@gmail.com"));
                 message.setRecipients(Message.RecipientType.TO,InternetAddress.parse("receiver@gmail.com"));
        message.setSubject("Testing Subject");
        MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
        mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
        mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
        mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
        mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
        mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
        CommandMap.setDefaultCommandMap(mc);
            message.setText(htmlBody);
                        message.setContent(textBody, "text/html");
            Transport.send(message);

            System.out.println("Done");

        } catch (MessagingException e) {
            e.printStackTrace();
        }

    }

}
Run Code Online (Sandbox Code Playgroud)


Kri*_*nck 6

我刚刚花了相当多的时间弄清楚如何使用JavaMail通过gmail或office365发送电子邮件。我在常见问题解答中找不到答案,但javadoc提供了一些帮助。

如果你忘记了,props.put("mail.smtp.starttls.enable","true")你就会得到com.sun.mail.smtp.SMTPSendFailedException: 451 5.7.3 STARTTLS is required to send mail

如果你忘记了,props.put("mail.smtp.ssl.protocols", "TLSv1.2");你会得到javax.mail.MessagingException: Could not convert socket to TLS;No appropriate protocol (protocol is disabled or cipher suites are inappropriate)。显然这仅对于 JavaMail 1.5.2 及更早版本是必需的。

这是让它工作所需的最少代码:

import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendEmail {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable","true");
        // smtp.gmail.com supports TLSv1.2 and TLSv1.3
        // smtp.office365.com supports only TLSv1.2
        props.put("mail.smtp.ssl.protocols", "TLSv1.2");
        props.put("mail.smtp.host", "smtp.office365.com");
        props.put("mail.smtp.port", "587");
        
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("test@example.com", "******");
            }
        });
        
        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("sender@example.com"));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient@example.com"));
            message.setSubject("You got mail");
            message.setText("This email was sent with JavaMail.");
            Transport.send(message);
            System.out.println("Email sent.");
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)