Send mail using Gmail from Java without turning on less secure app - java

I am attempting to send mail using Java to a Gmail account, code below. I appear to be doing everything correctly, however I receive an authentication failure. Google wants me to turn on the "less secure app" feature to enable transmission.
Is there a way to code in such a way that Gmail is happy with Java and will not throw the "turn on less secure apps" fault?
Error:
javax.mail.AuthenticationFailedException: 534-5.7.14 <https://accounts.google.com/signin/continue?sarp=...U
534-5.7.14 FigguJaZwDtp...
534-5.7.14 ...o> Please log in via your web browser and
534-5.7.14 then try again.
534-5.7.14 Learn more at
534 5.7.14 https://support.google.com/mail/answer/... - gsmtp
Code:
String hostSmtpUser = "myemail#gmail.com";
String host = "smtp.gmail.com";
String hostPort = "587";
String hostSmtpPassword = "thepassword";
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.user", hostSmtpUser);
properties.setProperty("mail.smtp.host", host);
properties.setProperty("mail.smtp.starttls.enable", "true");
properties.setProperty("mail.smtp.port", hostPort);
properties.setProperty("mail.smtp.auth", "true");
Session oSession;
if (true == ToolsCommon.isEmpty(hostSmtpUser))
oSession = Session.getInstance(properties);
else
oSession = Session.getInstance(properties, new javax.mail.Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(hostSmtpUser, hostSmtpPassword);
}
});
// Compose the message
try
{
MimeMessage message = new MimeMessage(oSession);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(Subject);
message.setText(Body);
// Send message
Transport.send(message);
}
catch (MessagingException ex)
{
// Log the error.
ToolsLog.logError(TypeLog.ui, ex);
}
I already did research, so the code to my knowledge is not the problem, just do not see a workaround for the less secure apps message.
References:
Ref 1
Ref 2
Ref 3
Ref 4

By default, GMail doesn't allow password-based authentication -- that's why you'd have to allow "less-secure apps" to use your program as-is.
Instead, you can use OAuth 2.0 to avoid using a password directly. That method is considered secure by Google and won't require changing any account settings.

Less secure apps (https://myaccount.google.com/u/0/lesssecureapps) options is disabled and we can longer use it to send mail.
But there is a better option provided by google - apppasswords
https://myaccount.google.com/u/0/apppasswords
Use 16 digit code provided by google instead of password and that should be it.
Note: 2-factor authentication needed to be enabled before using appspasswords.

Related

javax.mail.AuthenticationException - Google cloud app Engine - Spring Boot

I'm currently working on a spring boot application when i'm required to send mail at specific moment, so i used the javax.mail api to do so, the program works fine on local machine but when i deploy the application in google cloud app engine, i keep getting the following error:
javax.mail.AuthenticationFailedException
i tried to follow google cloud documentation instructions when it comes to mailing requirement but i keep getting the same error.
following my code.*
public boolean sendMail(String indicator, String destination, String hotelName, String username, String password) {
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "587");
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(env.getProperty(IConstants.mailAddress),
env.getProperty(IConstants.mailPass));
}
});
String indic = null;
if(indicator.equals("R")){
indic = "RECEPTIONIST";
}
if(indicator.equals("M")){
indic = "ROOMMAID";
}
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(env.getProperty(IConstants.mailAddress)));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(destination));
message.setSubject(indic + "Hotel " + hotelName + " - Credentials");
message.setText("Hello " + hotelName
+ " Employee, Down Below Your Credentials for a secure access to your workspace " + ".\n USERNAME: "
+ username + " PASSWORD: " + password + ".\n" + "Greetings.");
Transport.send(message);
return true;
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
The sender mail is on the authorized mail senders list, everything is correctly configured, the app responds to all the requests, but keeps failing at sending mail step.
I enabled the less security application authentication option on the sender gmail account but it keep rejecting the authentication attempts.
Thanks.
I kept trying multiple configurations to make it work but it didn't, so i switched to another option, i implemented the sendGrid solution, google cloud listed it as a possible alternative approach, it was so simple, so secure and it worked from first attempt.
SendGrid implementation
Thanks for ur suggestions
Were you using standard env or flexible env. In our case we used flexible env with google smtp mailing.
It is working fine for us. And I suspect the issue in your case is with the third party access check of google mail account.
Try the same smtp after enabling this option so that your application will be able to access the gmail smtp.
Turn on access from the settings shown in screenshot for the account which is being used from smtp
Although the sendgrid is a nice mailing service. But we prefered google smtp only.

Not able to send Mail in Java through SMTP server

When I try to send mail in java from my personal email like (sp#gmail.com) it is sent successfully.
But when I am using my company email(sp#example.com) it throws Authentication failed exception. I am using TLS authentication and it is successfully connected to host.
When I am manually login on my email it will always ask for Two Step
verification. Even if I have disabled my two step verification and have also done the change to make it less secure, it still asks for two step verification as it is showing this message after putting my username and password:
2-Step Verification
Based on your organization's policy, you need to turn on 2-step verification. Contact your administrator to learn more.
Enter one of your 8-digit backup codes
In this situation what should I do? As this is my first task in this company, I would be so happy if you could help me. How I can solve this problem?
My code :
String to = "abc#example.com";
String user = "sp#example.com";
String pass = "1234";
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.example.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(props,new javax.mail.Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(user,pass);
}
});
session.setDebug(true);
try
{
/* Create an instance of MimeMessage,
it accept MIME types and headers
*/
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(user));
message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));
message.setSubject(sub);
message.setText(msg);
/* Transport class is used to deliver the message to the recipients */
Transport.send(message);
}
catch(Exception e)
{
e.printStackTrace();
}
Error message:
535 5.7.3 Authentication unsuccessful javax.mail.AuthenticationFailedException at javax.mail.Service.connect(Service.java:319) at javax.mail.Service.connect(Service.java:169) at javax.mail.Service.connect(Service.java:118) at javax.mail.Transport.send0(Transport.java:188) at javax.mail.Transport.send(Transport.java:118) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPo‌​olExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.r‌​un(TaskThread.java:6‌​1) at java.lang.Thread.run(Thread.java:748)
SMTP configuration:
configuration:props.put("mail.smtp.host", "smtp.oceaneering.com"); props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
First is need to turn on 2-Step Verification .(after that google script to give new option for creation app passwords) https://support.google.com/accounts/answer/185839?
Next you must to create the app passwords https://support.google.com/accounts/answer/185833?hl=en
Last step to replace this line in your code
String pass = "1234"; - with app specific password, (it must generate on step 2) Some like String pass = "djd5n7hsd";
And For future reader in may be useful to check network and firewall setting on your system and mail setting your ISP. To check if packet can to reach gmail server.
Try telnet command : telnet smtp.gmail.com 587

javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful

I am sending e email using an SMTP error . I am getting Authentication unsuccessful. The username and password are correct. Am I doing something wrong.
The error logs are
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class EmailSender{
public static void main(String args[]) {
String to = "ssss#xxx.om"; // sender email
String from = "dddd#xxx.com"; // receiver email
String host = "dkdkdd.xxx.com"; // mail server host
String login="dkkdkd";
String pass="dkkdkd";
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.host", host);
properties.setProperty("mail.smtp.user", login);
properties.setProperty("mail.smtp.password", pass);
properties.setProperty("mail.smtps.ssl.enable", "true");
// properties.setProperty("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(properties); // default session
try {
MimeMessage message = new MimeMessage(session); // email message
message.setFrom(new InternetAddress(from)); // setting header fields
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("Test Mail from Java Program"); // subject line
// actual mail body
message.setText("You can send mail from Java program by using");
// Send message
Transport transport = session.getTransport("smtp");
transport.connect(host, login, pass);
Transport.send(message);
System.out.println("Email Sent successfully....");
} catch (MessagingException mex) {
mex.printStackTrace();
}
}
}
The error is
DEBUG SMTP: AUTH NTLM failed
Exception in thread "main" javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful
at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:826)
at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:761)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:685)
at javax.mail.Service.connect(Service.java:317)
at javax.mail.Service.connect(Service.java:176)
at javax.mail.Service.connect(Service.java:125)
at javax.mail.Transport.send0(Transport.java:194)
at javax.mail.Transport.send(Transport.java:124)
Had the same issue. It's an MS Exchange error that you receive. You are probably not allowed to use your email to send an email via a relay. The administrator of the Exchange server needs to give the rights to do that.
It has nothing to do with a configuration problem on the Java side.
It looks like the problem in how you do the session part...
try doing this:
private Properties emailPorperties;
...
...
emailPorperties = new Properties();
emailPorperties.put("mail.smtp.host", "your host");
emailPorperties.put("mail.smtp.socketFactory.port", "your port");
emailPorperties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
emailPorperties.put("mail.smtp.auth", "true");
emailPorperties.put("mail.smtp.port", "your port");
emailPorperties.put("mail.smtp.ssl.enable", "true");
emailSession = Session.getInstance(emailPorperties, new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
System.out.println("Authenticating");
return new PasswordAuthentication(USER_NAME, PASSWORD);
}
});
Hello i've got the same issue in the past.
So to solve it i have to connect on the webmail of my outlook or exchage and i noticed that these connexions were stopped by the server so inside i confirm that these transactions was mine.
So u have also to do it usually every 2 month in my case.
The problem is not in the code. The problem occurs because something is wrong with the configuration of the mailboxes I believe.
Same issue resolve by enabling IMAP of the sender email account in Exchange Control Panel (ECP) of outlook mail admin.
Go to your Microsoft admin account and turn off the multi-factor authentication.
By default it is enabled. Once you disable the multi-factor authentication then it works fine for me.
I had a similar issue and in my case, the issue was 'outlook password got expired'.
As I had it logged in default I did not have any issue while logging in to my mail.
I tried logging in to incognito mode and see if my logging asked for an additional layer for logging like multi-factor auth, And when logged in from the incognito tab it asked to change the password with a popup stating 'password got expired'.
I then updated the new password and it started to work fine !!

does sending email via SMTP with TLS connection encrypt the username and password?

I've written an appilicaiton with Java which sends Email. For sending Email I've used SMTP with TLS.
Recently I've searched about TLS and I found the flowing description about TLS on this website : Transport Layer Security (TLS), a protocol that encrypts and delivers mail securely, helps prevent eavesdropping and spoofing (message forgery) between mail servers.
The above phrase says that TLS guarantees that the mail will be delivered securely, but it does not say any thing about the password...
suppose that I am using following code in my application, so as you can see you need to have hard code for username and password, without any encryption.
final String username = "...#hotmail.com";
final String password = "your Password";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp-mail.outlook.com");
props.put("mail.smtp.port", "587");
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
by using this strategy does TLS encrypt my password while sending from my server to another server or not? should I be worried about it or not?
Password transmission and communication encryption are two separate matters.
TLS is initiated over what is at first an unencrypted channel by issuing the STARTTLS command; if the server supports it, then the exchange is done and after it is done, the channel is encrypted.
And only then the SMTP negotiation starts; and one part of this negociation is authentication if any. And even if you use the plain authentication mechanism (user and password sent over the wire as is), since the channel is encrypted at that time, eavesdroppers won't see it in clear.
Of course, for more security, you may choose to use another authentication mechanism than the plain one (CRAM-MD5 for instance; others exist).
EDIT OK, the answer above is only partially accurate; more details can be found in this excellent answer on ServerFault by #Bruno

Send Java email without authentication (no such provider exception: smtp)

The code I am currently using is as follows:
String to = "....#gmail.com";
String from = ".....#gmail.com";
String host = "127.0.0.1";
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.host", host);
Session session = Session.getDefaultInstance(properties);
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));
message.setSubject("This is the Subject Line!");
message.setText("This is actual message");
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException mex) {
mex.printStackTrace();
}
If I paste the above code in my Java servlet and run it, the following exception gets thrown:
javax.mail.NoSuchProviderException: smtp
I have also tried following the solutions outlined in these resources but to no avail: link1 link2 link3 link4.
It would help if you included the the full stacktrace for the javax.mail.NoSuchProviderException and JavaMail debug output. Because you are running this in a servlet container you could be running into Bug 6668 -skip unusable Store and Transport classes. Change your call to Transport.set to the following:
final ClassLoader ccl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(Session.class.getClassLoader());
try {
Transport.send(message);
} finally {
Thread.currentThread().setContextClassLoader(ccl);
}
That code will isolate which transport class the code is allowed to see. That will rule out that bug in your code.
NoSuchProviderException means something is messed up in your JavaMail API configuration. Where and how have you installed the JavaMail jar file?
Also, in case it's not clear from the other responses, the only way you're going to be able to send mail without authentication is if you're running your own mail server. You can't do it with general purpose online e-mail services (e.g. Gmail).
First of all, if you wanna use gmail to send emails from your program you need to define stmp host as gmail. Your current host "127.0.0.1" is localhost meaning your own computer? Do you have mail server running on your computer?
Here you can see some tutorial how to send an email using gmail: http://www.mkyong.com/java/javamail-api-sending-email-via-gmail-smtp-example/
If you're afraid to pass your normal gmail account details then create some kind of test email like kselvatest or something.
You are missing pretty much those:
final String username = "username#gmail.com";
final String password = "password";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
So basicly all you need to add is:
1.login and password so JavaMail can use some gmail account
2.declare which mail server you wanna use
change String host = "127.0.0.1"; to String host = "smtp.gmail.com";
3.set mail port
For this code you should get javax.mail.MessagingException: Could not connect to SMTP host: 127.0.0.1, port: 25; exception
But I suspect you have a jre issue. May be smtp implementation has a problem. Why don't you download java mail implementation from http://www.oracle.com/technetwork/java/javamail/index-138643.html and add it to your project class path and try?

Categories