0

I added Service Account to my email@gmail.com, activated OAuth2 for it and downloaded the key. Then I followed the steps described in this (life saving) post with the only difference that I instantiated "credential" from Json file (loading p12 would always give me "Invalid network password"). With this I can successfully get Access Token, here is the line which does it:

Task<bool> result = credential.RequestAccessTokenAsync(CancellationToken.None);

Then I instantiate SmtpClient from MailKit and try to connect and authenticate:

client.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
var oauth2 = new SaslMechanismOAuth2("email@gmail.com", credential.Token.AccessToken);
client.Authenticate(oauth2);

The last line generates exception that reads 555: 5.5.2 Syntax error, goodbye. l13sm3080685qtv.82 - gsmtp. The part that ends with .82 changes with each subsequent call. As per this post, I tried different variants for "email@gmail.com" (i.e. <email@gmail.com>). I also tried to use the Service Account email instead (the one similar to this: appName@serviceName.iam.gserviceaccount.com) but to no avail. I mad sure I am using latest versions of MailKit, MimeKit and Google.Api* and searched extensively but found nothing that could provide a solution.

Interestingly, without any change to the code I started experiencing different exception. It now comes partially base64 ecoded and reads this (after decoding): 334: {"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"}

In the meantime I tried 2 other implementations that claim they got it right. None works - they all succeed with getting access token but break on "authenticate". All of that blows once's mind and makes the effort even more hopeless. One wonders if there is any C# code that is truly successful in sending gmail message using OAuth2... Any hint or other form of help would be greatly appreciated.


The method pointed by jstedfast below works well but I'd like to follow up with few issues. Too much for standard comment, so I added it here:

When the flow is executed for the first time, it opens popup browser window and user must login/approve the application/service to access gmail account. It loooks like access key must be stored on the hard drive. If I removed "DataStore" from GoogleAuthorizationCodeFlow constructor, the browser seems to popup each time when executing the code. The app I have to fix normally runs without any user interaction. Is there a way to avoid browser popup by enabling/disabling something in gmail account or service/app defined in developer's console? If standard gmail account cannot be used this way, perhaps email that is a part of GSuite domain can? The customer who owns the application uses Google GSuite and they have their domain with emails and documents. I think that now I understand jstedfast's remark on client-to-server vs server-to-server.

pete.a
  • 31
  • 3

1 Answers1

0

Follow these directions to get this working: https://github.com/jstedfast/MailKit/blob/master/GMailOAuth2.md

If you are loading a .p12, then you are doing it wrong. That method is for service-to-service, not client-to-service. The instructions I provided above is for client-to-service.

jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • Thank you so much jstedfast - the method works like a charm ! Jut fyi: I am not useing p12 as I quickly learned I cannot overcome "invalid network password" when constructing X509 class. Anyway, I still need some help - added questions in the main post. Would you be able to point at a solution as reliable as the first one ? I value your thoughts/recommendations ! – pete.a Sep 19 '20 at 16:08
  • The problem with OAuth2 is that it requires periodic user-interaction, typically in the form of presenting the user with a web-browser UI and having them authenticate with GMail. There's not really a good way around it that I am aware of. That said, you can tell the user to go into their GMail settings and toggle "Enable less-secure apps" and then you can use a regular username & password combo rather than OAuth2. – jstedfast Sep 19 '20 at 16:18
  • Thanks a lot jstedfast, you surely known the subject. The fun-factor here is that I've been tasked with making the app working with GMail/GSuite accounts in a way that they do not have to be switched to "less secure" mode. I was hoping that with all those "secrets", "certificates" "IDs" and services/accounts/APIs a developer can get some break. Well does not look like that's the case... – pete.a Sep 19 '20 at 17:53