52 Stimmen

Verwendung von JavaMail mit TLS

Ich habe auf SO mehrere andere Fragen zur JavaMail-API und zum Versand von E-Mails über einen SMTP-Server gefunden, aber in keiner davon wurde die Verwendung von TLS-Sicherheit diskutiert. Ich versuche, JavaMail zu verwenden, um Status-Updates an mich selbst über meinen SMTP-Mailserver auf der Arbeit zu senden, aber das erfordert TLS, und ich kann online keine Beispiele dafür finden, wie man JavaMail verwendet, um auf einen SMTP-Server zuzugreifen, der TLS-Verschlüsselung erfordert. Kann mir jemand dabei helfen?

79voto

Sarat Punkte 1608

Wir haben in unserem Produkt einen Benachrichtigungscode, der TLS verwendet, um E-Mails zu versenden, wenn es verfügbar ist.

Sie müssen die Java-Mail-Eigenschaften einstellen. Sie brauchen nur die TLS-Eigenschaft, aber Sie brauchen möglicherweise SSL, wenn Ihr SMTP-Server SSL verwendet.

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");

Sie können dies dann entweder an eine JavaMail-Sitzung oder einen anderen Sitzungsinstanziator wie Session.getDefaultInstance(props) .

3 Stimmen

Herzlichen Dank! Buchstäblich alles, was ich tat, war die Zeile props.put("mail.smtp.starttls.enable", "true"); zu meinem Code hinzufügen und es funktionierte perfekt!

5 Stimmen

Beachten Sie, dass die Einstellung der Socket-Factory nicht mit modernen java.mail: stackoverflow.com/questions/17581066/

0 Stimmen

Sie können auch "mail.smtp.ssl.checkserveridentity" auf "true" setzen. Gemäß der docs : "Wenn auf true gesetzt, wird die Serveridentität gemäß RFC 2595 überprüft. Diese zusätzlichen Prüfungen, die auf dem Inhalt des Serverzertifikats basieren, sollen Man-in-the-Middle-Angriffe verhindern. Die Voreinstellung ist false. "

29voto

Guter Beitrag, die Zeile

props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");

ist obligatorisch, wenn der SMTP-Server SSL-Authentifizierung wie es der GMail SMTP-Server tut. Wenn der Server jedoch Klartext-Authentifizierung über TLS sollte es nicht vorhanden sein, da Java Mail sich darüber beschwert, dass die erste Verbindung im Klartext erfolgt.

Stellen Sie außerdem sicher, dass Sie die neueste Version von Java Mail verwenden. Kürzlich habe ich einige alte Java Mail Jars aus einem früheren Projekt verwendet und konnte den Code nicht zum Laufen bringen, weil der Anmeldevorgang fehlschlug. Nachdem ich auf die neueste Version von Java Mail aktualisiert hatte, wurde die Ursache des Fehlers klar: Es handelte sich um eine javax.net.ssl.SSLHandshakeException, die in der alten Version der Bibliothek nicht auftrat.

9voto

Brent Matzelle Punkte 3863

Die Einstellungen aus dem obigen Beispiel funktionierten bei dem von mir verwendeten Server nicht ( authsmtp.com ). Ich bekam immer wieder diese Fehlermeldung:

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

Ich habe die Einstellungen für mail.smtp.socketFactory entfernt und alles hat funktioniert. Die endgültigen Einstellungen waren wie folgt (SMTP-Auth wurde nicht verwendet und der Port wurde anderswo eingestellt):

java.util.Properties props = new java.util.Properties();
props.put("mail.smtp.starttls.enable", "true");

7voto

Renish Khunt Punkte 5438

Verwenden Sie einfach den folgenden Code. Er ist wirklich nützlich, um E-Mails über Java zu senden, und er funktioniert:

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();
        }

    }

}

6voto

Kristof Neirynck Punkte 3403

Ich habe gerade ziemlich viel Zeit damit verbracht, herauszufinden, wie man JavaMail verwendet, um E-Mails mit gmail oder office365 zu versenden. Ich konnte die Antwort nicht finden in der faq aber wurde ein wenig durch die javadoc .

Wenn Sie vergessen props.put("mail.smtp.starttls.enable","true") Sie erhalten com.sun.mail.smtp.SMTPSendFailedException: 451 5.7.3 STARTTLS is required to send mail .

Wenn Sie vergessen props.put("mail.smtp.ssl.protocols", "TLSv1.2"); Sie erhalten javax.mail.MessagingException: Could not convert socket to TLS; y No appropriate protocol (protocol is disabled or cipher suites are inappropriate) . Offenbar ist dies nur für JavaMail-Versionen 1.5.2 und älter notwendig.

Hier ist der minimale Code, den ich brauchte, um ihn zum Laufen zu bringen:

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);
        }
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X