Access Google Calendar API with username/password - c#

I am writing a small client to sync the outlook calendar on a machine with a user's google calendar. I am using .Net (C#).
I just read about accessing the Google Calendar API using the Google APIs Client Library for .NET and tried some basic stuff.
Now regarding the Authorization, as far as I understood, the new "OAuth 2.0" Authorization requires a "user consent", which means the user is directed to a google page where they must explicitly allow my application access to their calendar.
As if this user interaction is not enough, I as a programmer have to handle "access tokens" or "refresh tokens" and all that stuff.
Now my question is:
Is there really no easier way to have an installed application communicate with the google API to access a user's calendar?
I would like my user to enter his username/password in a "Settings" dialog. His credentials would be stored locally (encrypted of course) and then be used later on every access via google API. I know this can be dangerous and all that however I would like that decision to lie with me.
So, is that possible?

No that is not possible. The entire point of OAuth is the user never gives a 3rd party (you) their username and password. The only thing you get is a token that allows you to connect that the user can revoke at any time. (Also if the user changes his password, you can still use the same saved token and do not need to make the user update their settings).
If you decide to "work around" this by saving the username and pasword and performing the "authorization" yourself you will be in violation with the TOS of the API and will have your application banned by Google (or any OAuth provider if you try it with someone else) for not following the rules.

Related

How to read emails from an Outlook 365 account without user interaction for credentials?

My use case is as follows. At regular intervals, a daemon process needs to:
Scan an email account in Office 365 for Non-Delivery Reports,
Extract some info from the email body,
Perform a task for the user account identified from that info.
My approach was to use Microsoft Graph (at which I'm new) to get in and do this - however if there is an easier approach please let me know. I'm having trouble with the .NET graph API in authenticating & getting tokens without user interaction.
I have been successful in using a Microsoft Graph console sample (https://github.com/microsoftgraph/console-csharp-connect-sample) to connect to the email account, after doing the usual setting up of the app and its permissions/scopes in Office 365, and using the App ID and "secret" to connect.
However, after spending a whole day researching and trying various ways to authenticate in the sample app, it always pops up a login window (see https://i.imgur.com/SmtPpYd.png) before API actions can be performed. Sadly I've failed to discover how to authenticate and get tokens without user interaction.
Can anyone help me in how this sample needs to be modified - i.e. how the authentication needs to be altered - in order for it to work without asking the user to log in?
I do have full admin access, so can grant whatever permissions needed in Office 365, I just need help working out what to grant and what to alter in the console app to skip the user interaction. This is my first encounter with MS Graph and my head is spinning so please be gentle. :)
Note this will eventually run as a daemon on a server, but initially I'm just trying to learn by performing actions in this console app.
This application sample is using a public client (that can't store secrets because you don't control the device/OS/environment) as you can see here.
Here the acquire a token using apps public identity and user's identity (hence the prompt).
You have to replace it by a ConfidentialClientApplication instead providing an additional secret (that you can generate from the portal) and then replace the acquisition by a client only token request.
As your application is not going to hold any user identity none of the /me shortcuts are going to work.
Lastly, as you want to crawl all users, you need to change the permissions you're requesting to an admin permission/scope and replace User.Read and Mail.Read by User.Read.All and User.Read.All. (don't forget to click on the "grant permissions button" once you save the scopes.
Hopefully that helps

How to obtain credentials for Http Basic Authentiction

I'm writing a C# application and need to scrape some information from an rss page that only offers Http Basic Authentication.
This seems to leave me with two choices
Ask the user to input their credentials into my app (which has trust issues as the app is then a potential middleman attacker?)
Get windows to insert the credentials on behalf of my app somehow (does this facility exist?)
All the examples I've seen on SO have the username/password hardcoded in the app or passed in as parameters from somewhere unspecified. My use-case is I'd like to give this app to people who may not want to trust it with their password.
How is this usually handled? Thanks
Short answer: It is not possible with basic auth. It is generally not possible with the OS a the trusted instance.
Long answer:
The proper way to solve this would involve a procedure where your application hands control to the OS (Windows), which then asks the user "Do you trust application XY to use your identity?". After user acceptance, your application would receive a security token which you could use afterwards to make your HTTP request to get the RSS feed. The problem is, that the site in question does only accept basic auth. This means, that the "security token" is the base64-encoded username and password. So the username and password would be exposed to your application anyway.
The second problem is that the OS and the RSS site have to share a secret (i.e. an encryption key not available to you or anyone else not allowed to log in site users), to enable the OS to issue a secure token that is trusted by the RSS site.
How the problem can actually be solved
The default, real-world example for the access of web resources with third-party software on behalf of the user without knowing his password is OAuth, see for example the Facebook login flow. (However, this requires the website/resource in question to provide third-party access. As your question indicates, this does not apply for your use case.)
The pattern employed is the following:
Prerequisite: You need to register your application with the RSS service provider to obtain an application ID and an application secret.
Your application redirects the user to the login endpoint of the identity provider.
The user accepts (or declines) the access of your application to his identity and data (e.g. the RSS stream).
The identity provider redirects to your app
Your application receives a token which can be used to make authenticated requests on behalf of the user. This may involve additional steps like exchanging the token for another.
Alternative Solution (does not answer your question):
Sometimes (protected) RSS feeds can be accessed via secret user-specific URLs. Of course, the user would have to provide your application with that url.

Single sign on with ADFS

I am looking for single sign on for my application which is built on javascript (no server side language).
Requirement:
Agent log in to Windows (user integrated to Active directory)
Open my web page
Based on who logged in to windows, my application goes to AD and pull some user
specify data (eg email, phone)
How shall I go about it?
As per my understanding I will require ADFS for this.
So:
User goes to my web page
My web page calls some Web services or web application (which is build on c#)
That will authenticate against AD FS and get claim
Either get phone number and email in claim or get username and query AD for phone and email
Return the data to my web page (build on javascript)
It seems there something wrong in my understanding!!
Please suggest more appropriate solution based on my requirement
Frankly, I can't think of a way to make it work without a server side processing. This is because the ws-federation protocol ADFS uses is not just about returning claims.
It is about returing a SAML token. The token contains claims but what is most important about it is that it is signed using the XMLDsig. How are you going to validate the token is a first big question. But there are surely external libraries that allow that.
But then, such authentication can easily be bypassed by modifying scripts in the browser. This is because the ws-federation stops where you get the token and then it is up to you to exchange the token for the actual identity. And this won't work when processed only at the client side.
ADFS 3 does not support the OAuth2 implicit profile, which would be an option, but still you would need to verify the token on the server to avoid session fixation.
You can setup something like AuthorizationServer that supports Oauth2/OpenID Connect implicit profile
http://leastprivilege.com/2013/09/19/adding-oauth2-to-adfs-and-thus-bridging-the-gap-between-modern-applications-and-enterprise-back-ends/
Another option is to use something like Auth0 (Disclaimer: I work for Auth0) which also supports OAuth2/OpenID Connect implciit profile. In that case you wouldn't need ADFS, there is a connector/agent that you install on your network that does not require opening firewalls or anything and it supports implicit profile that is suited to JavaScript apps. This is an example of a single page app tutorial (if you create an account it will tailor the doc with your credentials):
https://docs.auth0.com/singlepageapp-tutorial

Is DotNetopenAuth good to get user credentials?

I want to ccreate a website that reads one's Gmails headers.
If I use dotNetopenAuth to authenticate -
will I eventually get the user user and password for my applications' needs?
It seems that the answer is no- for security reasons that's why OpenId is for.
But then, I know website that do so. How?
If you use protocols like OpenID or OAuth, you will not have access to the user's userid nor password.
Instead you will receive a unique identifier for the user, which does nothing more than tell you that the trusted provider has validated that the user logged into their provider's account successfully. It is your job to match that unique identifier with your application's user record.
Depending on the provider you use for authentication (Google, Yahoo, MyOpenId, Twitter, etc.), you may request additional information such as the user's email address and name, but you are not guaranteed to get even that.
Under no circumstances will you ever get to see their password, though. If you want that, then you will have to write your application to use your own authentication provider, like the built-in ASP.NET Membership provider.
The point of OpenID is as you say: delegate authentication to another so that you don't have to deal with the password (if there even is one).
Sites that have the user log in with Google, and then gain access to that user's data at Google aren't just using OpenID. They're also using another authorization protocol. Google supports a proprietary one and a more common standard one called OAuth. OpenID and OAuth can be combined such that the user visits Google just once to log in, and then your site gains the access it needs (if the user approves).
If you take a look at the DotNetOpenAuth sample OpenIdRelyingPartyWebForms\loginPlusOAuth.aspx you'll see an example of the user logging into Google, and by doing that giving the site the ability to download the user's Google address book. This can be easily changed to include permissions to do other things (like read email headers) but you'll need to read Google documentation (GData) to learn what scope to use and APIs to call to obtain this information.
Under no circumstances should you be collecting the user's Google password yourself. I suspect that would be a violation of the Google terms of service anyway.

Twitterizer OAuth login for desktop app without web UI

I want to write an application which can update an twitter status of an certain twitter account.
The user has to log in to twitter.
I want to make this application with Twitterizer, but since it uses oAuth, the user needs to go to the twitter website to tell twitter that my application is granted access to the user's twitter account.
Because I want to make a very simple twitter application for people who are not really even expert with computers, I don't really want that process.
Is there any option to automate the web UI of the oAuth process? Or an option to don't use that web UI?
The purpose of OAuth is to ensure that the user is aware that they are granting a 3rd party access to their account. If OAuth allowed the process to be automated, it would undermine the very reason it exists.
One way around asking the user to copy/paste a PIN, is to use the HttpListener class to create a simple webservice that runs on the client's computer. You can create it long enough to listen for the user to be directed back to the callback url and capture the values needed. I've demonstrated this technique on my blog.
Just as commentary: to say "but since [Twitterizer] uses oAuth" insinuates that it was my design decision (I'm Twitterizer author), where it is really the security protocol required to interact with the Twitter API. Every Twitter library requires the use of OAuth.

Categories