Problem (Authentication failed):
Initially Gmail authentication through Chilkat failed and after analyzing we found that we have to turn ON "allow less secure apps" for the Gmail account to login successfully.
Proposed Solution by Chilkat:
To avoid turning ON "allow less secure apps" in every Gmail account, we followed solution provided at GMail OAuth2 example
Please find the detailed steps we followed and error code below and help us to resolve this:
1) We created a certificate file(.p12).
Through the service account(in developer console) and we have the service account email address as well.
2) I am able to generate accesstoken successfully.
NSString *accessToken = [http G_SvcOauthAccessToken: iss scope: scope subEmail: sub numSec: [NSNumber numberWithInt: numSec] cert: cert];
3) Connecting to "imap.gmail.com mail" server succeeded.
success = [imap Connect: @"imap.gmail.com"];
4) But when I try to authenticate to gmail account using any gmail ID the authentication fails.
success = [imap Login: @"firstname.lastname@example.org" password: accessToken];
This is a very much misunderstood topic, and one that is not clearly explained in any of the Google documentation (as far as I know). My current understanding of the issue is as follows.
There are two types of OAuth2 authentication procedures:
(See the OAuth2 Bible for a good summary. The flows for Two-Legged OAuth1.0a and Three-Legged OAuth1.0a are the same as for OAuth2, except the content of the messages is different.)
Three-Legged OAuth2 requires the owner of the resource (i.e. the owner of the GMail account) to interactively provide authorization to allow the application to access the GMail account. In a web application, this involves a callback to a Google URL to interactively get permission.
If your application is not running in a browser, then this is not possible. (or it is possible in an clunky and awkward way using an embedded or external browser that involves having the GMail account owner paste a URL and then copy/paste a PIN back to the application)
What most people want is this: An application owned by themselves to access a GMail account also owned by themselves. In other words, the application is not trying to access some GMail account owned by some other person. (To put it simply: It's MY GMail account, and it's MY application. Why can't I have MY application access MY GMail account without jumping through hoops as if the GMail account was owned by somebody else???)
This is where two-legged OAuth2 SHOULD solve the problem, but it doesn't. Not for consumer GMail accounts. It is possible with a Google Apps account where the email address is NOT a gmail.com email address.
Two-legged OAuth2 is used with a Service Account. See https://developers.google.com/identity/protocols/OAuth2ServiceAccount To quote the Google documentation:
So... to work with your own data, you must have your own Google Apps domain. A consumer GMail account uses the "gmail.com" domain -- which is not your domain. (Gmail.com is Google's domain.) You must have a Google Apps account were GMail is used for an email address at your own domain. (See https://apps.google.com/products/gmail/ )
Assuming you have a Google Apps domain and you are using GMail for an email address at your own domain, then it is possible to do two-legged OAuth2 via a "service account" (see https://developers.google.com/identity/protocols/OAuth2ServiceAccount ) You'll need to create the Google service account and then "Delegating domain-wide authority to the service account.", and then it is possible to do two-legged OAuth2. (But again, not for a consumer GMail account. If the email address ends with ".gmail.com", then it is a consumer GMail account..)
To send using OAuth2, you would need a Google Apps account. You can't use OAuth2 to send email for a consumer GMail account.
Also see the instructions for Delegate domain-wide authority to your service account here:
answered Apr 21 '16 at 09:33