I implement a IMAP gmail client using Oauth 2.0 that work fine on development mode. I can connect to IMAP, search e-mails, insert labels... but when I deploy my application, throw me an error here:
IMAPStore store = OAuth2Authenticator.connectToImap("imap.gmail.com",
993, "user#email.com", oauth, true);
Error:
Empty username or password. f5if721432qez.143
I use the same code of the examples of Google: http://code.google.com/p/google-mail-oauth2-tools/wiki/JavaSampleCode
Have to configure something else on production?
Related
I have basic legacy asp.net web application (no mvc, no .net core)
As of May 30 2022 google has stopped supporting less secure apps. So now if I want to send an email with mywebapp#gmail.com as from address, its not working!
SmtpException: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.0 Authentication Required. Learn more...
I have tried setting up apppassword and sending mail using NetworkCredentials, it works but straight afterwards I get an Application_OnError event raised and again the above SmtpException is thrown.
Some googling says to resolve this I needed to implement OAuth2.0, but this relates to using user's gmail account or some permissions related to this gmail account.
which is irrelevant in my scenario. I only want to send emails to my customers from mywebapp gmail account, not the user's account.
Then why should my customer (while using mywebapp) give consent to receive emails from mywebapp gmail account? given they dont have login credentials.
how is OAuth2.0 relevant in my scenario?
Feeling confused.
Side Question: If you think apppassword is the way to go then why am I receiving smtpexception after the email is successfully sent? can share code if required
My smtpClient code
Public Function SendViaGmail(subject As String, body As String, recipients As String)
Dim fromEmail As String = ConfigurationSettings.AppSettings("ContactEmail")
Dim smtpClient As Mail.SmtpClient = New Mail.SmtpClient("smtp.gmail.com") With {
.Port = 587,
.DeliveryMethod = SmtpDeliveryMethod.Network,
.Credentials = New NetworkCredential(fromEmail, "APP_PWD"),
.EnableSsl = True
}
Dim mailMessage As MailMessage = New MailMessage With {
.From = New Mail.MailAddress(fromEmail),
.Subject = subject,
.Body = body,
.IsBodyHtml = True
}
mailMessage.[To].Add(recipients)
If smtpClient IsNot Nothing Then
smtpClient.Send(mailMessage)
End If
End Function
My full post related is mentioned here
Why do I need OAuth when sending emails to my clients via gmail?
Answer: You do not, necessary it depends on the use case.
There are two ways to send emails via the smtp server now that google has removed less secure apps.
you can enable 2fa on the google account and create an apps password
you can then take the exact same code you used before and simply replace the standard user gmail password with the apps password.
the second option would be to use xoauth2.
How is OAuth2.0 relevant in my scenario?
XOauth2 is a form of Oauth2 which allows an application to request consent of a user to access their private data in this case their gmail mail account. Using XOauth to imo would be over kill in your user case if you are only connecting to your own Gmail account then there is really no reason for you to use Xoauth2 and authorize a user.
Side Question: If you think apppassword is the way to go then why am I receiving smtpexception after the email is successfully sent? can share code if required
An smtpexception would imply to me there is an error in your code.
Note: Working example can be found in authors other question SmtpClient not working after setting up app password and 2-factor authentication enabled
I've gone through the process of creating an OAuth2 access token for a test application on my Google account (not using GSuite) and whenever I try to use it to authenticate using XOAUTH2 with imap.google.com, it fails and returns {"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"} followed by the IMAP status response NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)
I've seen some other similar issues raised, and it turns out the problem was because they didn't use the scope https://mail.google.com/ when requesting the token. However, I did use that scope and the token validates; using https://www.googleapis.com/oauth2/v1/tokeninfo it returns:
{
"issued_to": "xxxxx.apps.googleusercontent.com",
"audience": "xxxxx.apps.googleusercontent.com",
"scope": "https://mail.google.com/",
"expires_in": 2083,
"access_type": "offline"
}
The thing is, the same token works just fine with authenticating using Google's POP3 server, connecting to pop.gmail.com. It seems to be an issue specific to IMAP, and I checked, both POP3 and IMAP access are enabled for the Gmail account I'm testing with.
In addition, the same IMAP code which performs the XOAUTH2 authentication works just fine with Outlook and their access token. So I'm at a loss as to why Google is rejecting a valid token when I'm using the broadest scope available.
Any suggestions or insights would be welcome.
After doing some more testing, I was able to get this to work. The solution won't likely be helpful for anyone who isn't rolling their own OAuth2 code, but here was the problem. I was encoding the AUTHENTICATE request like this (where ^A is the SOH control character):
^Auser=username#gmail.com^Aauth=bearer ya29.a0AfH6SMA8fcO_RkV3sH73f.....^A^A
Google's POP3 server was completely fine with this, and so was Outlook's mail servers. However, Google's IMAP server apparently had a real issue with "bearer" not being capitalized. After reviewing RFC 7628, and despite this explicitly in the standard:
Note to implementers: The SASL OAuth method names are case insensitive. One example uses "Bearer" but that could as easily be "bearer", "BEARER", or "BeArEr".
Changing the request to use "auth=Bearer" instead of "auth=bearer" allowed the client to authenticate. This is clearly a Google issue, but at least it's resolved.
I can use the Javamail IMAP package to access my outlook.office365.com mailbox. I want to access the same mailbox by using OAuth2.0. According to https://javaee.github.io/javamail/OAuth2, after 1.5.5 JavaMail is able to support OAuth2 by using the Bearer access token. I created a simple testing code:
System.out.println("Helloworld");
String host="outlook.office365.com";
String username="mymailboxname";
//String password="mymailboxpasswd";
String accesstoken="eyJ0eXAiOiJKV1QiLCJub25jZSI6Im4....my token from Micorsoft .....S0QoWgvodHXw";
Properties props=new Properties();
props.setProperty("mail.imap.ssl.enable","true");
props.setProperty("mail.imap.auth.mechanisms","XOAUTH2"); //added for oauth2
// set any other needed mail.imap.* properties here
Session session=Session.getInstance(props);
Store store=session.getStore("imap");
// store.connect(host,993,username,password);
store.connect(host,993,username,accesstoken);
When I ran it, I got AuthenticationFailedException
Exception in thread "main" javax.mail.AuthenticationFailedException: AUTHENTICATE failed.
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:732)
at javax.mail.Service.connect(Service.java:366)
at Main.main(Main.java:21)
What is the way to connect to outlook.office365.com with IMAP by using OAuth2
Found on here
Note
If you've enabled security defaults in your organization, POP3 and IMAP4 are automatically disabled in Exchange Online. For more information, see What are security defaults?.
To protect your Exchange Online tenant from brute force or password spray attacks, your organization will need to Disable Basic authentication in Exchange Online and only use Modern authentication in Exchange Online. Disabling Basic authentication will block legacy protocols, such as POP and IMAP.
I am using Google Business Apps for emails, and trying to send emails through PHPMailer. Now there is an issue with the SSL certificate so I have to turn off the SSL verification, but this errors is thrown up:
Auth method requested: XOAUTH2
Auth methods available on the server: PLAIN,LOGIN
SMTP Error: Could not authenticate.
Now my host isn't particularly helpful as its saying I need to use the correct email/pass, but that's not the way it works as we have to create an App via Google Developer and the connection is verified.
I am wondering if XOAUTH2 needs to be installed to the server? I have access to cPanel, but can't find the module.
Read the troubleshooting guide that the error links you to.
I'd bet that your ISP is intercepting your traffic and redirecting you to their own mail server, which will fail to match gmail's SSL certificate, and also lacks gmail's XOAUTH2 authentication scheme.
You should pay attention to why you're getting these errors - certificate verification is there to protect you and when it fails a check it's telling you that someone is intercepting your traffic and trying to MITM you - and by disabling it you've already given away your gmail credentials.
I'm sending emails using PHPMailer 5.2.10 with the next code:
function SendGmail($to,$subj,$body)
{
$mail = new PHPMailer(); // create a new object
$mail->IsSMTP(); // enable SMTP
$mail->SMTPDebug = 1; // debugging: 1 = errors and messages, 2 = messages only
$mail->SMTPAuth = true; // authentication enabled
$mail->SMTPSecure = 'ssl'; // "ssl" secure transfer enabled REQUIRED for GMail
$mail->Host = "smtp.gmail.com";
$mail->Port = 465; // 465 or 587
$mail->IsHTML(true);
$mail->Username = "admin#mydomain.ru";
$mail->Password = "********";
$mail->SetFrom("admin#mydomain.ru");
$mail->Subject = $subj;
$mail->Body = $body;
$mail->AddAddress($to);
return $mail->Send();
}
Note: we use Google Apps, so the mail domain is not google.com, but some other, let's say, mydomain.ru.
Everything was fine until Google had recently implemented another "security enhancement" (AFAIK forcing OAuth2 authorisation). Now PHPMailer->Send() returns the following text:
2015-05-12 06:49:15 CLIENT -> SERVER: EHLO 127.0.0.1
2015-05-12 06:49:15 CLIENT -> SERVER: AUTH LOGIN
2015-05-12 06:49:15 CLIENT -> SERVER: [some base64 string]
2015-05-12 06:49:15 CLIENT -> SERVER: [some base64 string]
2015-05-12 06:49:16 SMTP ERROR: Password command failed: 535-5.7.8 Username and Password not accepted. Learn more at 535 5.7.8 http://support.google.com/mail/bin/answer.py?answer=14257 u10sm3566045lbb.30 - gsmtp
2015-05-12 06:49:16 SMTP Error: Could not authenticate.
2015-05-12 06:49:16 CLIENT -> SERVER: QUIT
2015-05-12 06:49:16 SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting bool(false) Done!
Ok, I go to http://support.google.com/mail/bin/answer.py?answer=14257 and doing the following:
Logging to this account via web interface - everything's Ok,
Opening this link in browser: http://www.google.com/accounts/DisplayUnlockCaptcha - google says everything is Ok,
Opening this link: https://support.google.com/accounts/answer/6010255 and then this link: https://www.google.com/settings/security/lesssecureapps where I see the following:
"Access for less secure apps: * Turn off / * Turn on" - for normal gmail account,
("This setting is inaccessible for google apps accounts") - for google apps account (not the exact text but my translation from russian as google shows it).
Yes, I have tried both SSL and TLS, 485 or 587 ports and everything else I've found on stackoverflow.com and here: https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting . Nothing helped.
PHPMailer troubleshooting page suggests to use "an OAuth2 client class": http://www.phpclasses.org/package/7700-PHP-Authorize-and-access-APIs-using-OAuth.html - but I have no idea of how to integrate it into PHPMailer and why it's not integrated yet by PHPMailer developers (this class is under BSD license), while it's necessary now for one of the most popular mail servers. I found no documentation for this OAuth2 about integrating it into PHPMailer, and I'm sure I can't do it myself - my PHP knowledge is poor.
The question is:
How can I avoid this goddamn OAuth2 and send emails as I did it before this "security enhancement" (for google apps account)? --OR:
How to easily integrate OAuth2 class mentioned above into PHPMailer? --OR:
Are there any other easy-to-use PHP solutions to send emails using gmail?
Lots of thanks in advance.
Thank you for reading the docs, it's much appreciated! The problem is that google has imposed this complicated authentication mechanism without much regard for its users, as you have experienced. It doesn't improve security because ultimately you still have to submit a username and password over SSL to get your token. OAuth is an authorisation (what you can do) protocol, but google are using it indirectly as an authentication (who you are) protocol.
The reason that nobody has implemented it is that while it's very clever, OAuth is generally unpleasant and confusing to work with, which is why we'd be very happy if someone got around to implementing it!
This article is very helpful and might form the basis of a PHPMailer implementation. Though that adds a dependency on ZF2, the principles will be the same for any other OAuth implementation such as the one from PHPClasses I linked to or this one.
Sorry I can't be much more help on this.
Update: PHPMailer now supports OAuth for gmail. This article describes how to use it, and yes it is still quite unpleasant!
How can I avoid this goddamn OAuth2 and send emails as I did it
before this "security enhancement" (for google apps account)?
You can't. Unlike regular Google, Google Apps does not allow "less secure apps". And once your account has been flagged for extra security, you must switch to OAuth2.
How to easily integrate OAuth2 class mentioned above into PHPMailer?
You can't. Like the Thunderbird team, there is some pretty strong bias against OAuth2 in the PHP Mailer team. IMO, OAuth2 is a big improvement for email.
Are there any other easy-to-use PHP solutions to send emails
using gmail?
Yes. My solution for my own SMTP project, Postman, was to switch from PHP Mailer to Zend_Mail for OAuth2. Zend_Mail has had native OAuth2 support for quite a while.
Oops, that was my mistake, I've been editing the code in wrong place, not in the one it was executed from.
Strange, but in spite of OAuth2 and other google surprises, i had not to change anything to make old code work (just update password).