C# OAuth2 SMTPclient.Authenticate() exceptions - c#

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.

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.

Related

Is there a way to get current Google Authenticator 2FA key for a specific account (client-side)

I am searching for a way to obtain the current code in my Google Authenticator app. for a specific account.
Please note that I'm not looking for embedding Google 2FA to any of server-side application - I guess it has been already well-documented.
I am trying to get the same current code shown in my own Google 2FA app. (by providing my Google credientials ofcourse) so I can make my app fully automated even when logging in (to a specific system/website) without asking for the code each time I start the app.
Thanks by now.
UPDATE:
Even if I can't find any answer or simply "there is no way", there is still a way even if it's too ugly.
Running an ios/android simulator (and configure it once by installing the Google Auth app) and simulate the mouse clicks over it and then capturing a screenshot and decoding the code from the image would be much of a work but also can actually work. I'm just trying to find a better way, if there is any.
You could solve this by generating the OTP code locally using a library such as OTP.Net. Simply save the secret locally, and add it to .gitignore if using git.
Then you can make a code on demand like so:
using OtpNet;
var totp = new Totp(secretKey);
var totpCode = totp.ComputeTotp();

How to get a developer key for ViaGogo API

Long shot, but I'd like to fiddle with ViaGogo API (C# library more precisely). ViaGogo has a well documented public API, documentation is avaliable here.
Problem is, you need to authenticated as it usually happens with this kind of APIs: usually, you find a section of the website, maybe in your profile section, where you can obtain keys, secrets and so on (this happens for example on Facebook or Amazon).
As for ViaGogo, I only found a link that points to a Google Form: this form asks for info about advertising and affiliation on a complete different level of what I need, I won't publish anything read via API. Furthermore, there's no field to leave an e-mail address.
Their C# library seems pretty popular as far as I can tell from downloads from NuGet; I wonder how all these thousands of devs succesfully called that API.
Has anyone succesfully obtained authentication info from ViaGogo?
According to note in registration form, you have to wait for 30 days for their reply.
For more help you can contact them on following contacts:
E-mail: affiliate#viagogo.com
Telephone: +442075532777
Or
http://www.viagogo.com/in/help
There doesn't seem to be any way around this registration according to their website and the api itself -- an appID and password is required. You may try your luck emailing them at Affiliate.Team#viagogo.com -- see this issue on github where the possibility of getting an account via email is discussed: https://github.com/viagogo/developer.viagogo.net/issues/24

Google External Login Fails with no Error Message - But Facebook Works

I'm using MVC External Authentication providers for both Google and Facebook. I have easily gotten both working many times before.
For some reason today, on a brand new project (File | New Project | MVC 5 Web App) in VS 2015 - it is the completely default project. The only thing I have done is provide the App Keys and Secrets for both Google and facebook.
Facebook works all the way through, calls back - asks me to register as a new user - and then logs me in as that user.
Google gets all the way to the point where it WOULD call back to the OAuth Callback url - but that never happens, and instead I'm just redirected back to the login page with no further explanation. There are no errors, no messages are logged anywhere that I can find, and no exceptions are thrown.
If instead, I register as a password user, and then try to link the account - I am able to do so without any trouble with facebook. However, again, with the Google external provider, it gets to the point where the OAuth callback uri WOULD Be triggered, but instead, it just take me back to the "/ManageLogins" page with the generic error "An Error has Occurred".
I have enabled every type of exception that I could possible trap - but I get absolutely no feedback from the process except that it didn't work. And since I literally have not yet had a chance to write a single line of code, I'm not sure what else to try.
I have spent almost 6 hours now trying to get this basic identity management part of the project completed - and while it usually only takes 10-15 minutes, I am completely blocked. And since there is so little feedback from the code itself, I'm hoping that someone has run into this before and might be able to help.
Thanks.
Other Things I've tried:
1) it was original http - I thought that might be the problem, so I got an ssl certificate - and have converted it to https. Same problem.
2) I have cleared my cookies, tried incognito, tried in many browsers - always the same result.
3) Original it was a new project in a larger solution - so I have now just created a new web project in it's own solution. Same problem.
4) I have switched to 2 different domains, and tried it from localhost of course.
Running out fo things to try....
EJ
I know its an old thread, but I ran into the exact same issue. You have to make sure that Google+ API is enabled in Google Developers Console.

Google-drive example: oauth2callback not found

I need a little help with the C# example program of Google-Drive...
I used this so-called "tutorial"/"example":
https://developers.google.com/drive/examples/dotnet
And the code from here:
https://code.google.com/p/google-drive-sdk-samples/source/checkout
I uploaded my (only slightly modified) sourcecode here in case anybody doesn't have Mercurial (I didn't have Mercurial and no admin rights to install it either, and Mercurial is the only way to get the sourcecode...):
http://verzend.be/elt0k13enraw/DrEdit.rar.html
I always get
"Ressource cannot be found"
Requested URL: /oauth2callback
I don't find this astonishing, as no oauth2callback controller or handler is implemented...
I tried adding a Controller called oauth2callbackController and redirecting to another action in oauth2callbackController.Index, doing
return new RedirectResult("/about/about");
But that only creates a NULL-reference exception.
So i figured, maybe the wrong controller and redirected to
return new RedirectResult("/drive/Index");
But that only creates an infinite loop of redirect -> allow -> redirect - allow -> etc.
BTW, the config to change the API key + REDIRECT_URI is in
Models\ClientCredentials.cs
Note:
The problem aren't my modifications.
The sample also didn't work unmodified, with the exact same error.
All I did was removing EntityFramwork references, and throwing "Not implemented exception" when a method using entity was called.
Edit:
Additional information:
What I really wanted to do in the first place is to write a console service that exports my database, LZMA-compresses the exported content, encrypts that with OpenPGP, and uploads the database of my server to Google drive every day at 24:00 o'clock, without any user input.
I got export working without a problem, i got the LZMA compression working without a problem, I got the encryption with PGP working without a problem.
After the end of the working day (grrrr), when I was at home, I was even able to download the example-code with the mercurial installed on my Linux-machine at home, and bring it on the windows machine using SMB...
But now I can't get the sample for the Google-drive SDK working...
And moreover, what I really need is an example for a console service/daemon, not a web-application.
When I created the API key, I saw one could create a key for a service, but there is no example on how to write a Google-Drive service (console application), and no useful documentation as well (yea there is a reference, but it's only a reference, IntelliSense provides about the same)...
When configuring your app in the API Access tab of the APIs Console, you had to set the root (/) of your web server as the redirect URI and not /oauth2callback.
Assuming that your app is published at www.example.com, just go back to the APIs Console and set it to www.example.com instead of www.example.com/oauth2callback

Is Java/1.6.0_24 a Bot and How to force them to refresh their link

We've now got plenty of sites which all use a log4net base error loging framework and we receive error from site from anywhere it append. We've notice that some of them catch error because of "Bot" like google, bing, yahoo, etc. But there's a things we've not sure about how to resolve. I've two questions about it :
Is "Java/1.6.0_24" a Bot? Because the user-agent of my question #2 is about this.
The "Java/1.6.0_24" still calling subfolder on our site that just do not exists! Like, if we have a page called "Page1.aspx", instead of calling "~/Page1.aspx", he calls it "~/minisite/Page1.aspx". How can I tell him he's wrong? Is there a way to do it?
Thanks you
It's most likely a bot but it could as well be some kind of browser based on Java that sends that user-agent string - you can't trust it 100% but it can give you an estimate idea of what the connecting entity is. Depending on the kind of bot it might as well just ignore your robots.txt so I'd just impement some handling stuff somewhere.
Did those folders ever exist? If so, you could use HTTP's permanent redirect (code 301) to tell him to no longer look there - however that doesn't guarantee it will do so.

Categories

Resources