javaMail: send mail using google oauth caused javax.mail.AuthenticationFailedException.
Properties props = new Properties();
props.put("mail.smtp.ssl.enable", "true"); // required for Gmail
props.put("mail.smtp.auth.mechanisms", "XOAUTH2");
Session session = Session.getInstance(props);
Transport transport = session.getTransport("smtps");
transport.connect("smtp.gmail.com", 465, xyz#gmail.com, oauth_access_token);
The oauth access token is valid, just refreshed, about 20 seconds before running the code.
Error:
javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8 https://support.google.com/mail/?p=BadCredentials s136sm158338qka.106 - gsmtp
at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:965)
at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:876)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:780)
at javax.mail.Service.connect(Service.java:366)
From the logging, it seems that auth is using username/password, not OAUTH. guide: https://javaee.github.io/javamail/OAuth2
Logging:
DEBUG: JavaMail version 1.6.2
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 465, isSSL true
220 smtp.gmail.com ESMTP s136sm158338qka.106 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 465
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
DEBUG SMTP: protocolConnect login, host=smtp.gmail.com, user=xyz#gmail.com, password=<non-null>
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN failed
In case someone comes across this page: JavaMail does work with Gmail OAuth2 authentication. The following is how it works on my Kotlin code base:
The props needed for Session is shown below (it's in yaml format, but you get the idea):
javamail:
config:
"mail.smtp.host": smtp.gmail.com
"mail.smtp.port": 587
"mail.smtp.starttls.enable": true
"mail.smtp.starttls.required": true
"mail.smtp.auth.mechanisms": XOAUTH2
When constructing an email (multi-part or not), the enclosing mime message must be bound to a Session that has all the above props. This can be easily missed when using a class from a library to construct an email (like SimpleEmail):
val session = Session.getInstance(javamail.config().toProperties())
val email = SimpleEmail().apply {
setMailSession(session) // do not forget this line
setCharset("utf-8")
setFrom(credInfo.email())
addTo("someone#somewhere.com")
setSubject("Test email")
setMsg("This is the test.")
buildMimeMessage()
}
Call a static method Transport.send(msg, username, password), where username is your email, and password is your fresh access-token. There's no need to create an instance of Transport, nor a need to call transport.connect():
Transport.send(email.mimeMessage, gmail, accessToken)
I think you need to disable the plain authentication to force Jakarta Mail to use XOAUTH2.
props.put("mail.smtp.auth.plain.disable", "true");
Trying the following code:
Properties props = new Properties()
props.setProperty("mail.smtp.host", "smtp.gmail.com")
props.setProperty("mail.smtp.port", "587")
props.put("mail.smtp.auth","true")
props.put("mail.smtp.starttls.enable", "true")
props.put("mail.smtp.starttls.required", "true")
props.put("mail.smtp.auth.mechanisms", "XOAUTH2")
props.put("mail.smtp.auth.login.disable", "true")
props.put("mail.smtp.auth.plain.disable", "true")
props.put("mail.smtp.auth.ntlm.disable", "true")
props.put("mail.debug", "true")
props.put("mail.debug.auth", "true")
Session session = Session.getInstance(props)
String emptyPassword = ""
final URLName unusedUrlName = null
SMTPTransport transport = new SMTPTransport(session, unusedUrlName)
transport.connect("smtp.gmail.com", googleEmail, googleAccessToken)\
Multipart multipart = new MimeMultipart()
BodyPart messageBodyPart = new MimeBodyPart()
def from = googleEmail
def to = "test#test.com"
def subj = "TestOath2Gmail"
def body = "TTT"
message.setFrom(new InternetAddress(googleEmail))
message.addRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress(to))
Date sentDate = new Date()
message.setSentDate(sentDate)
message.setSubject(subj)
messageBodyPart.setContent(body, "text/html")
multipart.addBodyPart(messageBodyPart)
message.setContent(multipart)
transport.send(message)
Getting error:
DEBUG SMTP: Using mechanism XOAUTH2
AUTH XOAUTH2
235 2.7.0 Accepted
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: protocolConnect returning false, host=smtp.gmail.com, user=username, password=
Since migrating a production Rails app to a new machine, the follow error is always recieved when trying to send mail via Mandrill:
OpenSSL::SSL::SSLError (hostname "smtp.mandrillapp.com" does not match the server certificate)
Here is the
config.action_mailer.smtp_settings = {
address: 'smtp.mandrillapp.com',
port: '587',
enable_starttls_auto: true,
user_name: 'XXXXXXXX',
password: 'XXXXXXXX',
authentication: 'login', # Mandrill supports 'plain' or 'login'
domain: 'mydomain.com' }
Mandrill down not allow for openssl_verify_mode: 'none' as suggested here: Rails 3: OpenSSL::SSL::SSLError: hostname was not match with the server certificate
When openssl_verify_mode: 'none' is set the error becomes:
Net::SMTPAuthenticationError (535 Incorrect authentication data)
Any ideas on how to correct this?
I encountered and solved this issue (my Rails app is hosted on a WHM/cPanel account).
The trick was tweaking the SMTP Restrictions in the WHM settings, specifically turning off the following setting:
"Restrict outgoing SMTP to root, exim, and mailman (FKA SMTP Tweak)"
I have to send e-mails from a Rails application, and am trying to do so with ActionMailer. The mail administrator created a new account for the purpose that requires no authentication; I am able to send messages with this new account with msmtp using a configuration like (in ~/.msmtprc)
account myapp
auth off
host mailserver.domain
port 25
from myapp#domain
user myapp#domain
password
In the development.rb file I introduced a similar configuration:
config.action_mailer.raise_delivery_errors = false
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'mailserver.domain',
from: 'myapp#domain',
port: 25,
domain: 'domain',
authentication: 'off',
user_name: 'myapp#domain',
password: '',
enable_starttls_auto: false }
config.action_mailer.perform_deliveries = true
But whenever a mailing method is invoked I get the following exception:
(0.7ms) ROLLBACK
Completed 500 Internal Server Error in 387ms
Errno::ECONNREFUSED (Connection refused - connect(2)):
app/models/user.rb:28:in `send_admin_mail'
app/controllers/registrations_controller.rb:15:in `create'
I imagine something is wrong or missing in the development.rb file, but I have no idea what it may be. Any help is appreciated.
Update: Following eugen's suggestion below I found that at execution time ActionMailer::Base.smtp_settings does not contain the correct settings; in particular, address is pointing to localhost instead of pointing to the mail server:
=> "{:address=>\"localhost\",
:port=>25,
:domain=>\"localhost.localdomain\",
:user_name=>nil,
:password=>nil,
:authentication=>nil,
:enable_starttls_auto=>true}"
How can I correct this?
Actually, your configuration has some problems. Just like the the 'from:' key, it should not be placed in smtp_settings. As for other possible problems, please refer RubyonRails.guides
Hope to do some help.
So I am having trouble setting up this rails application(OpenProject, if it makes a difference).
When I try the send a test mail in the openproject settings it displays a message in that the e-mail was sent but I don’t ever receive it at the address.
config/configuration.yml
production:
delivery_method: :smtp
smtp_settings:
tls: true
address: "smtp.gmail.com"
port: '587'
domain: "smtp.gmail.com"
authentication: :plain
user_name: "your_email#gmail.com"
password: "your_password"
development:
delivery_method: :smtp
smtp_settings:
tls: true
address: "smtp.gmail.com"
port: '587'
domain: "smtp.gmail.com"
authentication: :plain
user_name: "your_email#gmail.com"
password: "your_password"
test:
delivery_method: :test
If I use:
telnet smtp.gmail.com 587
Trying 64.233.171.108...
Connected to gmail-smtp-msa.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP r1sm2094806qam.42 – gsmtp
This leads me to think I can send to gmail but I cant receive from gmail. I have also tried all of the configurations such as port 25 and 456 as well as with SSL vs TLS and none. so I don't think it is just my ISP blocking the mail.
In my google settings → accounts and Import → add another email address you own
Send mail through your SMTP server.
SMTP server: smtp.my_domain_name.com
Port: 587
Username: my_username_on_my_domain
Password: passwd
TLS (recommended) ← (I have this selected)
SSL
I get the message
Couldn't reach server. Please double-check the server and port number.
I did run
netstat -a
If the results of that would be helpful let me know.
Any help would be greatly appreciated. Thanks.
Unfortunately there is no any logs in your question. Please note:
Gmail Api Do not support sent email from different adress(protect from spam/spoof)
Rails can send email from self application and this options tell him what host use.
Consider config.action_mailer.raise_delivery_errors = true to debug your code and settins.
I have problem with delivering emails on production server.
When mailer processed new message, calls exception Net::OpenTimeout (execution expired)
My smtp settings:
#settings.yml
production:
smtp:
address: smtp.gmail.com
port: 587
domain: mydomain.net
user_name: username#gmail.com
password: password
authentication: plain
enable_starttls_auto: true
My environment settings:
#production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = Settings.smtp.symbolize_keys
From logs:
Sent mail to username#gmail.com (30010.1ms)
I, [2014-10-15T12:59:22.371563 #19779] INFO -- : Completed 500 Internal Server Error in 30051ms
F, [2014-10-15T12:59:22.373984 #19779] FATAL -- :.
Net::OpenTimeout (execution expired):
app/controllers/subscribers_controller.rb:9:in `create'
My VPS provider (DigitalOcean) blocked SMTP on IPv6 by default :(
I had to disable IPv6 on server with next config:
# /etc/sysctl.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
Apply settings:
$ sysctl -p
Uncomment the next line in /etc/gai.conf to prefer IPv4:
precedence ::ffff:0:0/96 100
And remove IPv6 DNS from /etc/resolv.conf:
nameserver 2001:4860:4860::8844 # remove lines like this
nameserver 8.8.8.8 #don't remove
Then restart application and Nginx (optional)
I had the same issue, in my case it was because Google Cloud Compute platform blocks outgoing connections to SMTP servers outside of Google's domain on ports 25, 465, and 587.
To fix this problem we had to connect to a non-standard SMTP port (most API-based mailer platforms support 2525 as well for this reason).