My Java Windows app needs to send email and allow the user to specify his/her email account credentials: host, port, username, password. It works when I use my credentials for an account at my hosting service, but not so well when using a Gmail account, as my prospective users might want to do. The problem is Gmail insists on an "App password." So, I follow the Google instructions and create a 16-character App password which Google says has to be used one time only. However, I find that the App password MUST be used for subsequent runs.
Here's a sample program that demonstrates the problem. It will fail if I use that actual password for the Gmail account. It will work after I've created an App/device specific password (16 characters) and used it as the password, as it should. But, I have to use that 16-character password thereafter as well. What am I missing?
public class SendEmailTLS {
// Example 1 from https://www.mkyong.com/java/javamail-api-sending-email-via-gmail-smtp-example/
public static void main(String[] args) {
final String username = "me123#gmail.com";
final String password = "mypassword";
Properties prop = new Properties();
prop.put("mail.smtp.host", "smtp.gmail.com");
prop.put("mail.smtp.port", "587");
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.starttls.enable", "true"); //TLS
Session session = Session.getInstance(prop,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("me123#gmail.com"));
message.setRecipients(
Message.RecipientType.TO,
InternetAddress.parse("you456#hotmail.com")
);
message.setSubject("Testing Gmail TLS");
message.setText("Dear sir,"
+ "\n\n I'm testing TLS,using port 587");
Transport.send(message);
System.out.println("Done");
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
I want to add that I'm now suspecting that what I'm seeing is the way it's supposed to work. I had been thinking the 16-char App specific pw was a "Salt" kind of thing to protect the Gmail server. I have now read that it's really just an alternative password for my Gmail account. If anyone can confirm or deny this new perspective, I would be grateful.
Related
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.
public class Office365TextMsgSend {
Properties properties;
Session session;
MimeMessage mimeMessage;
String USERNAME = "xxxx#xxxx.xx";
String PASSWORD = "xxxxxxx";
String HOSTNAME = "smtp.office365.com";
String STARTTLS_PORT = "587";
boolean STARTTLS = true;
boolean AUTH = true;
String FromAddress="xxxx#xxxx.xx";
public static void main(String args[]) throws MessagingException {
String EmailSubject = "Subject:Text Subject";
String EmailBody = "Text Message Body: Hello World";
String ToAddress = "xxxxxx#gmail.com";
Office365TextMsgSend office365TextMsgSend = new Office365TextMsgSend();
office365TextMsgSend.sendGmail(EmailSubject, EmailBody, ToAddress);
}
public void sendGmail(String EmailSubject, String EmailBody, String ToAddress) {
try {
properties = new Properties();
properties.put("mail.smtp.host", HOSTNAME);
// Setting STARTTLS_PORT
properties.put("mail.smtp.port", STARTTLS_PORT);
// AUTH enabled
properties.put("mail.smtp.auth", AUTH);
// STARTTLS enabled
properties.put("mail.smtp.starttls.enable", STARTTLS);
properties.put("mail.smtp.ssl.protocols", "TLSv1.2");
// Authenticating
Authenticator auth = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(USERNAME, PASSWORD);
}
};
// creating session
session = Session.getInstance(properties, auth);
// create mimemessage
mimeMessage = new MimeMessage(session);
//from address should exist in the domain
mimeMessage.setFrom(new InternetAddress(FromAddress));
mimeMessage.addRecipient(RecipientType.TO, new InternetAddress(ToAddress));
mimeMessage.setSubject(EmailSubject);
// setting text message body
mimeMessage.setText(EmailBody);
// sending mail
Transport.send(mimeMessage);
System.out.println("Mail Send Successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Error:
javax.mail.AuthenticationFailedException: 535 5.7.139 Authentication
unsuccessful, SmtpClientAuthentication is disabled for the Tenant.
Visit https://aka.ms/smtp_auth_disabled for more information.
[MA1PR01CA0169.INDPRD01.PROD.OUTLOOK.COM]
As the error explicitly states, SMTP authentication is disabled. It even provides you with a very helpful link to https://aka.ms/smtp_auth_disabled. The link explains how to enable SMTP AUTH for the whole organization or only for some mailboxes.
AAD security defaults may block this. I had:
Get-TransportConfig | Format-List SmtpClientAuthenticationDisabled
SmtpClientAuthenticationDisabled : False
But still got 535 5.7.139 authentication unsuccessful
It turned out it was Security defaults in AAD that was the problem
Turn off Security Defaults in Azure Active Directory
Start by logging into the Azure Active Directory (https://aad.portal.azure.com/).
Select Azure Active Directory
In left menu click: Azure Active Directory
Select Properties from the menu under Manage
AAD properties
Select Manage security defaults at the very bottom of the properties page
Managing security defaults
Move the slider to No and click Save
save security defaults
You may then check:
Next login to or navigate to the Microsoft 365 Admin Center https://admin.microsoft.com/
Select Settings > Org Settings
Under Services, select Modern Authentication
Ensure Authentication SMTP is checked
I have a simple web application where different users can log into it. One of the important feature is user can access a document and send email of it's content to an outsider like third party. Below is just how the email looks like to give an idea:
It's pretty self explanatory and I can send to multiple user if I want like abc#example.com,efg#hotmail.com,... in the field box shown.With all this, I am using Java Mail API to make it work and after hitting the send button,it sends directly to the recipient.No issue at all.
Now, I want to modify this by doing this email feature as a service.What this means is when I send the email,the content and info filled in will be stored in a table in MYSQL and the service(running in background) will pick up from the table and do the sending.
This is my function:
public void sendEmail(String recipient, String subject, String content,
String host, String port, final String senderaddress,
final String password) {
try {
System.out.println("Please Wait, sending email...");
/*Setup mail server */
Properties props = new Properties();
props.put("mail.smtp.host", host); //SMTP Host
props.put("mail.smtp.port", port); //TLS Port
props.put("mail.smtp.auth", "true"); //enable authentication
props.put("mail.smtp.starttls.enable", "true"); //enable STARTTLS
//create Authenticator object to pass in Session.getInstance argument
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(senderaddress, password);
}
};
Session session = Session.getInstance(props, auth);
session.setDebug(true);
// Define message
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(senderaddress));
message.addRecipients(Message.RecipientType.TO,
InternetAddress.parse(recipient));
// Set Subject: header field
message.setSubject(subject);
// Now set the actual message
message.setText(content);
try {
Transport.send(message);
} catch (AddressException addressException) {
addressException.printStackTrace();
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
Can this be done in the way I want because I am unsure how to make it work?
1 ) After hitting Sending mail button from UI, You need to call a method for saving data like recipient, subject, content in DB
2)Write an email sender Service which retrieves non_delivered / pending mail from DB table and send it through Java Mail API
3)Scheduled email sender service with the help of ScheduledExecutorService
I'm having trouble with error
javax.mail.AuthenticationFailedException: 535 5.7.3
Authentication when trying to send an email. I've tried using two different email accounts. One using Office365 server details and the other using Gmail server details.
In both cases I get the same error. My code is below. Outside of my code the email addresses can send and receive email successfully without issue. This is my email class as it is the part that isn't working. All other aspects of my program work. Any help you can provide is greatly appreciated.
public class SPUREMAIL{
//CONSTANTS - Things that will never change
private static final String HOST = "smtp.office365.com";
private static final String PORT = "587";
private static final String SENDER = "EMAIL";
private static final String PASSWORD = "PASSWORD";
private static final String SUBJECT = "Spur Design has shared a file with you";
private static final String MESSAGE = "This email message was sent from an unmonitored address. Please contact your Spur Design representative for any questions or concerns";
//this item will change, its the direct link to the file
private String URLToFile;
private String recipient;
public SPUREMAIL(String URLToFile, String recipient){
this.URLToFile = URLToFile;
this.recipient = recipient;
}
//Properties for email
private Properties getProperties(){
Properties properties = new Properties();
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", HOST);
properties.put("mail.smtp.port", PORT);
properties.put("mail.smtp.user", SENDER);
properties.put("mail.smtp.password", PASSWORD);
return properties;
}
//Creating an email session so I can authenticate to server
Session session = Session.getInstance(getProperties(), new javax.mail.Authenticator(){
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(SENDER, PASSWORD);
}
});
public void sendMail(){//This will actually attempt to send the email successfully
try{
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(SENDER));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
message.setSubject(SUBJECT);
message.setText(MESSAGE);
Transport.getTransport("smtp");
Transport.connect(HOST, SENDER, PASSWORD, pass);
Transport.sendMessage(MESSAGE, message.getAllRecipients());
}
catch(MessagingException e){
System.out.println("send failed, exception: " + e);
}
System.out.println("Sent!!!!");
}
}
Few suggestion which you can try and check if they work for you.
If you are trying outlook, I am assuming you are trying to connect your internal organization email servers. Try with port 25 and check if setting mail.smtp.starttls.enable to false make a difference.
I don't think you need to use username and password. You can remove it in case of outlook. You will need that in case of gmail.
You might want white-list your ip address by the firewall team. They have to allow connection from your machine.
Try installing a local email server, I have used papercut and it works like a charm.
Before sending your email using gmail you have to allow non secure apps to access gmail you can do this by going to your gmail settings.
Good luck.
have you checked this link -
javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful
It says it could the mail server configuration issue for your organization where your email id is not allowed to send mail via code. May be your mail server administrator can help here.
Also, this link - https://confluence.atlassian.com/confkb/unable-to-send-email-due-to-javax-mail-authenticationfailedexception-error-message-151519398.html , says the cause could be the mail server configured incorrectly.
Sometimes a pretty change will make a huge response, this case is also like that. You have to give full mail address at username. Sender's mail id's username should be with #domain.com
username : ******_****#domain.com
The issue with my code was two-fold. One, the email class was not being compiled when I compiled the entirety of my project. This was causing my Transport calls to go unchecked. Changed the Transport calls to the bloc below and after manually compiling email class successfully I was able to send emails perfectly fine. All credit goes to Bill Shannon for pointing me in the right direction.
public void sendMail(){//This will actually attempt to send the email successfully
try{
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(SENDER));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
message.setSubject(SUBJECT);
message.setText(MESSAGE);
Transport.send(message, message.getAllRecipients());
}
catch(MessagingException e){
System.out.println("send failed, exception: " + e);
}
System.out.println("Sent!!!!");
}
}
I have an automated java mail application that sends automated mail to users when some important update occur in our database. It was working fine. However it started to give me errors and I realized that it's not working.
The error says:
"Please log in via your web browser and then try again.
Learn more at https://support.google.com/mail/bin/answer.py?answer=78754 l10sm7526045oev.7 - gsmtp"
The java mail application that I write is huge and contains some confidential values(password etc.), I decided to write a sample demo to show you what's going on. It gives me the same error. Please assume that javax.MAIL API has been imported to the project. Here is what I have:
public class MailDemo {
public static void main(String[] args) {
final String userName = "dummyEmail#gmail.com";
final String password = "dummyPassword";
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");//Smtp server address
props.put("mail.smtp.port", "587");//port for the smtp server
Session session = Session.getInstance(props, new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(userName, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("dummyEmail#gmail.com"));//from email address
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("dummyEmail#gmail.com"));//to email address
message.setSubject("My first Email");//Subject of the mail
message.setContent("<h1>This is a test email</h1>", "text/html; charset=utf-8");//Content of the mail
Transport.send(message);//send the message
System.out.println("Email Stiation:Done!");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Well, i found the problem. Actually the codes are correct. It's gmail. it blocks the sign in attempts.I think that gmail thinks the attempts are not real.
I am sending email using
public void sendEmail(String fromEmailAddr, String toEmailAddr,String subject, String emailBody) {
String host = "xxx";
final String user = "user";
final String password = "password";
// Get system properties
Properties properties = new Properties();
// Setup mail server
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", "25");
// Get the default Session object.
Session session = Session.getDefaultInstance(properties, null);
try{
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(fromEmailAddr));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmailAddr));
// Set Subject: header field
message.setSubject(subject);
// Now set the actual message
message.setText(emailBody);
// Send message
Transport.send(message);
System.out.println("Sent message successfully....");
}catch (MessagingException mex) {
mex.printStackTrace();
}
}
When i try to send email using above code then it comes to message Sent message successfully.... but i got no email. On the other hand if i use authentication then i got the email
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(properties,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user,password);
}
});
Why ? Is it necessary to provide userName and password for host ? Can i send email by just specifying host, no username and password provided ?
Thanks
I guess the port number might be the issue.
Try changing properties.put("mail.smtp.port", "25");
to properties.put("mail.smtp.port", "587");.
Further you can refer this.
It depends on the mail server you're using.
For example, some mail servers will let you send mail to anyone in the same company without authentication, but authentication is needed to send mail outside of the company. In the latter case, if you send the mail without authenticating, the mail server may accept the message and return a "mailer-daemon" failure message, or might just throw the message away.
Also, see this list of common JavaMail mistakes.