Cannot send mail over SSL or TLS using SMTP using Javamail

Happy New Year!

I am working on an application in which the user receives an email whenever a specific trigger occurs.

This is the function I use to send email:

public static void sendEmail(String host, String port, String useSSL, String useTLS, String useAuth, String user, String password, String subject, String content, String type, String recipients) throws NoSuchProviderException, AddressException, MessagingException { final Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.smtp.host", host); props.setProperty("mail.smtp.port", port); if (useSSL != null && !useSSL.equals("false") && useSSL.equals("true")) { props.setProperty("mail.smtp.ssl.enable", useSSL); props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.smtp.socketFactory.port", port); } if (useTLS != null && !useTLS.equals("false") && useTLS.equals("true")) { props.setProperty("mail.smtp.starttls.enable", useTLS); props.setProperty("mail.smtp.socketFactory.fallback", "true"); } props.setProperty("mail.smtp.auth", useAuth); props.setProperty("mail.from", user); props.setProperty("mail.smtp.user", user); props.setProperty("mail.password", password); Session mailSession = Session.getDefaultInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(props.getProperty("mail.smtp.user"), props .getProperty("mail.password")); } }); Transport transport = mailSession.getTransport(); MimeMessage message = new MimeMessage(mailSession); message.setHeader("Subject", subject); message.setContent(content, type); StringTokenizer tokenizer = new StringTokenizer(recipients, ";"); while (tokenizer.hasMoreTokens()) { String recipient = tokenizer.nextToken(); message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipient)); } transport.connect(); transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO)); transport.close(); 

Oddly enough, whenever I try to run the above code using the main method, it will successfully send an email for SSL and TLS protocols.

 public static void main(String args[]) { try { Notifier.sendEmail("smtp.gmail.com", "587", "false", "true", "true"," sender_email@gmail.com ", "testpassword", "CHECKING SETTINGS", "CHECKING EMAIL FUNCTIONALITY", "text/html", " cc_email@gmail.com "); } catch (Exception ex) { ex.printStackTrace(); } } 

But it fails when I try to run the same code through my web application.

Sending over SSL causes this error:

 com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required. Learn more at jvm 1 | 530 5.5.1 https://support.google.com/mail/answer/14257 f12sm88286300pat.20 - gsmtp jvm 1 | jvm 1 | at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2057) 

Sending through TLS causes this error:

 javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 587; jvm 1 | nested exception is: jvm 1 | javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection? jvm 1 | at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1934) 

Any help is appreciated.

EDIT1:

Here is the tpl file from the front end

 <div class="label1"><h3 class="label">Host:</h3></div> <div class="field1"><input type="text" class="input1" name="host" size="20" value="$HOST$"></div> <div class="port"><h3 class="label">Port:</h3></div> <div class="fieldport"><input type="text" class="fieldport" name="port" size="5" value="$PORT$"></div> <div class="ssl"> <input type="radio" name="sslEnable" value="$SSLENABLE$"> Enable SSL? </div> <div class="tls"> <input type="radio" name="tlsEnable" value="$TLSENABLE$"> Enable TLS? </div> <div class="auth"> <input type="checkbox" name="auth"$AUTH$> Enable Authentication? </div> <div class="label2"><h3 class="label">User:</h3></div> <div class="field2"><input type="text" class="input1" name="user" size="20" value="$USER$"></div> <div class="label3"><h3 class="label">Password:</h3></div> <div class="field3"><input type="password" class="input1" name="password" size="20" value="$PASSWORD$"></div> <div class="label4"><h3 class="label">Recipient(s):</h3></div> <div class="field4"><input type="text" class="input1" name="recipients" size="50" value="$RECIPIENTS$"></div> 

Values ​​are saved in a configuration file that looks like this:

 host=smtp.gmail.com port=587 ssl=false tls=true auth=true user=send_user_email@gmail.com password=O0UbYboDfVFRaiA= recipients=cc_user_email@gmail.com trigger1=false attempt=0 trigger2=false percent=5 anyOrAll=ANY trigger3=true format=HTML trigger4=true trigger5=true 

EDIT2:

 public static void sendEmail(String message) throws NoSuchProviderException, AddressException, MessagingException { if (message == null || message.trim().equals("")) return; StringBuffer content = new StringBuffer(); content.append(getHeader()); content.append(message); content.append(getFooter()); String format = NotifyProps.getFormat(); String type = "text/plain"; if (format.equals(NotifyProps.HTML)) type = "text/html"; sendEmail(NotifyProps.getHost(), NotifyProps.getPort(), Boolean.toString(NotifyProps.getUseAuth()), Boolean.toString(NotifyProps.getUseSSL()), Boolean.toString(NotifyProps.getUseTLS()),NotifyProps.getUser(), NotifyProps.getPassword(), "Transaction Processor Auto Notification", content.toString(), type, NotifyProps.getRecipients()) } 

This is the class that sets and gets the properties:

https://codeshare.io/5G8ki

Thanks.

+5
source share
5 answers

Although your code looks fine, there is at least one big problem. You are trying to use the same port (587) for TLS and SSL. I'm not sure about TLS, but the SSL code should work IF you send your request to port 465. As it is written here (Google Frequently Asked Questions) :

setting up your SMTP server on port 465 (with SSL) and on port 587 (with TLS) [...]

They have their own ports. The error you get for SSL:

 Unrecognized SSL message, plaintext connection? 

Your client does not understand that he received a non-SSL-encoded response (due to the fact that the TLS port does not implement SSL).

+2
source

We have several properties set for TLS

 props.put("mail.smtp.starttls.enable", "true"); props.setProperty("mail.smtp.ssl.enable", "true"); props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.socketFactory.fallback", "false"); 

For Auth use smtps instead of smtp

 props.setProperty("mail.smtps.auth", useAuth); 

Upon receipt of transport

 session.getTransport("smtps"); 

Pass the host email and password again when connecting

 transport.connect("smtp.gmail.com", " user@email ", "password"); 

For debugging

 session.setDebug(true); 
+1
source

Try using the following code for me.

 public void sendEmail(){ Properties props = new Properties(); props.put("mail.smtp.host", "smtp.gmail.com"); props.put("mail.smtp.socketFactory.port", "465"); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.port", "465"); Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(" senderEmail@gmail.com ","secret"); } }); try { Message message = new MimeMessage(session); message.setFrom(new InternetAddress(" from-email@gmail.com ")); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(" to-email@gmail.com ")); message.setSubject("This is testing message"); message.setText("Hi this is testing email....not spam"); Transport.send(message); System.out.println("email successfully sent.."); } catch (MessagingException e) { throw new RuntimeException(e); } } 
0
source

Gmail has recently had a security update. You must enable the "Allow access to secure applications" setting at https://myaccount.google.com/security?pli=1 . Then you can send letters from your account without any problems.

0
source

simple-java-mail has a simple enumeration that you can use to specify SSL or TLS. You do not need to worry about the correct properties this way:

 Email email = new Email(); (...) new Mailer("smtp.gmail.com", 25, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email); new Mailer("smtp.gmail.com", 587, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email); new Mailer("smtp.gmail.com", 465, "your user", "your password", TransportStrategy.SMTP_SSL).sendMail(email); 

If you enable two-factor login, you need to create a password for a specific application from your Google account for this example to work.

0
source

Source: https://habr.com/ru/post/1240146/


All Articles