This post describes how to do OAuth authentication for non-web (eg. desktop) .NET applications. It uses the AppHarbor API as an example, but the approach should be applicable to other OAuth authenticated resources. The approach is inspired by the "Using OAuth 2.0 for Installed Applications" Google documentation.
We only realized the need for a non-web OAuth flow after announcing the AppHarbor API contest where we gamely suggested you guys build various desktop apps using the API, without providing a useful way to authenticate these kinds of apps.
If you're working on your AppHarbor API contest entry and not interested in all the details, just grab the AppHarbor SDK from GitHub and have a look at the console application sample. We've folded the flow into the SDK to make authorizing desktop apps as simple as possible.
The crux of the approach outlined below is that the user never has to enter his username and password into the 3rd party client app. Username/password authorization only happens on AppHarbor, and the client app then authorizes future API calls with the token obtained using OAuth. The token can be reset by the user later on if he wants to revoke access for the application. The fact that the user never types his username and password into the application prevents skullduggery of the sort where the client app stores the users credentials forcing the user to change his password to revoke access.
- Application decides it needs to authenticate user
- Application starts a web server listening on a known localhost url using
- App fires up user's favourite browser and opens the AppHarbor OAuth authorization page with a
localhost redirect url
- User signs in to AppHarbor (if not already logged in) in the browser window
- User authorizes the application on AppHarbor
- User is redirected to the localhost url
- The localhost web server gets the request and the application sniffs the OAuth authorization code from the request url
- The application can now trade the authorization code for a token and start issuing API requests
Check out the AppHarborClient.Auth.cs for all the gory details of how this works.