OAuth Has Ruined Everything

oath_header

OAuth Sucks. I’m probably not telling you something that you don’t already know. If you’ve ever had to setup authentication to one (or heaven forbid) multiple authentication providers (Google, Facebook, Twitter, Instagram, etc.), then you already know that it’s enough to make anyone want to switch careers.

Nobody has ever implemented an OAuth flow for their application and then said, “That was fun. Let’s do it again.”

Don’t believe me? Just go to Twitter and search for “OAuth Sucks”. Or just search “OAuth”. Or best of all just follow the OAuthSucks Twitter account. It’s a sentiment that’s so common, it has it’s own Twitter account. How did I find this account? I tried to register it of course.

But why is OAuth so awful? And does it have to be this way? In this post, we’ll take a look. OAuth (2.0 specifically) has a litany of problems, starting with the fact that the 2.0 spec itself essentially allows anything to be considered “OAuth compliant”.

OAuth And The Road To Hell

In an article called “OAuth And The Road To Hell”, Eran Hammer, who was originally on the OAuth 2.0 working group, talks about why he left, asked them to withdraw his name from the specification and even called it “the biggest professional disappointment of my career.” Now granted, that was 2012. He may have had a bigger disappointment since then.

To summarize the post for you, pressure from enterprise interests resulted in a spec that did not really enforce an opinion on anything and left all implementation details up to interpretation. It’s essentially a spec that was designed to conform to whatever the implementer needed it to look like. A specification that is different depending on what you need it to look like is no specification at all.

All pipe is to be made of a long hole, surrounded by metal centered around the hole.

No fittings are to be put on pipe unless specified. If you do, straight pipes become crooked pipes.

– Excerpt from The Piping Specification (Unknown Source)

Even more damning than that is the fact that the main problem with the OAuth 1.0 specification was that it was overly complex. There is a site called OAuthBible whose sole purpose is just to explain the concept of OAuth. Hammer called the 2.0 spec more complicated than 1.0.

So OAuth is complex, confusing, and the people that created it can’t agree on whether or not it’s bad, or just plain horrible. But the fact remains that it is how you have to authenticate to third party providers most of the time. And since, as Eran explained, the spec allows implementers to do anything they want, each and every provider has to explain to you how to do OAuth based on the way they implemented it.

The only thing worse than OAuth is the attempt by all of the implementers to explain to developers how to actually use it. You basically need to be an expert on everyone’s proprietary implementation, which is exactly what specifications are supposed to mitigate.

The truly sad part of all of this is that, in my opinion, social logins are one of the best things to happen to the web in recent years.

Nobody Wants To Register

Registering for applications is a tax that nobody really wants to pay, especially on mobile devices. Social logins are the “registration tax loophole”. Most of us are already on social media in some form or another. Even if you just scope to Twitter, Facebook and Google, you’re probably going to be able to cover most everyone.

Our social networks already know too much about us (I’m looking at you over-sharers). Instead of having to register for every new service we want to try, we can just tell them to verify with one of these social networks that we are who we say we are. In fact, this might be the only real value social networking services deliver. And here you thought it was all memes, vines and pithy quotes about how happy people are on their anniversaries.

“Burke, you sound so bitter.” I know. That’s what happens when you deal with OAuth.

When implementing social logins, we don’t actually want to use a third party API, we just want to ask them to verify a user. That should be easier right? HAHAHAHA….no.

Adding Google Sign-In

Let’s look at just Google for a minute. Google has an authentication flow specifically when you just want a button that says “Sign In With Google”. Does it use OAuth? How would I know. It doesn’t say.

What it does say is that one can “Enable Google Sign-In with only a few lines of code.” ORLY? Let’s find out.

Google wants you to include a script in the head of your page and an element that the script will turn into a button. When you click on that button, a modal window will open and you will have the chance to authenticate using Google. When you sign in, the window closes and there is a global callback that fires. This is what it looks like.

<html lang="en">
  <head>
    <meta name="google-signin-scope" content="profile email">
    <meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
    <script src="https://apis.google.com/js/platform.js" async defer></script>
  </head>
  <body>
    <div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
    <script>
      function onSignIn(googleUser) {
        // The ID token you need to pass to your backend:
        var id_token = googleUser.getAuthResponse().id_token;
        console.log("ID Token: " + id_token);
      };
    </script>
  </body>
</html>

That’s pretty much straight from the docs. And you know what? It works.

google-sign-in

The user signs in, and you get a token back. Done right? WRONG.

That token means jack squat. In fact Google says, “If you use Google Sign-In with an app or site that communicates with a backend server, you might need to identify the currently signed in user on the server.”

Well, since that’s virtually every application ever, there is now another step to the process. The client-side flow gets you the token, but now you need to verify that token. If you scroll down, it tells you to send the token to your server and then validate that…

  • The ID token is a JWT that is properly signed with an appropriate Google public key (available in JWK or PEM format).
  • The value of aud in the ID token is equal to one of your app’s client IDs. This check is necessary to prevent ID tokens issued to a malicious app being used to access data about the same user on your app’s backend server.
  • The value of iss in the ID token is equal to accounts.google.com or https://accounts.google.com.
  • The expiry time (exp) of the ID token has not passed.
  • If your authentication request specified a hosted domain, the ID token has a hd claim that matches your Google Apps hosted domain.

Awesome. A bunch of terminology that I don’t know. Lucky for you, Google has some libraries that are going to help you out. Down at the bottom of the page, they show you how easy it is to authenticate using the Java Google API Client Library. What if you’re not using Java? Well, they have a Python example too.

Not using Java or Python? Then you’re screwed.

In my case, I was using .NET. Hmmm. No library for .NET. Let’s check NuGet.

nuget

Google API…that looks like it. Let’s use that one. I’ll just use the same namespaces that the Java library uses because they would be consistant right? No. Of course they aren’t. So let’s do some Googling to see if we can figure out if anyone has every successfully done this with .NET.

All of my hits bring me back to the same GitHub sample project that looks like a low level implementation of WHAT IS THIS I DON’T EVEN.

what is this

As it turns out, what Google is actually wanting here is an implementation of JWT, or JSON Web Tokens, yet another specification for you to learn. There is a .NET library available for JWT, but good luck trying to figure out how to implement it. I eventually pulled it off, but only after lifting code from what’s got to be the most obscure message board on the internet. So obscure that I can’t find it anymore.

If you’re interested in how to validate JWTs with .NET, here is a Gist that contains the code that I lifted.

At Telerik, we’re all about making the developer experience better, and I can’t think of a worse development experience than OAuth. Telerik Backend Services was designed to mitigate this sort of nonsense. Let’s take a look at how it works.

Google Login With Telerik Backend Services

First, we need to enable Social Authentication in our project in the Platform Dashboard.

enable-social

Now we can work directly with the Backend Services API (AKA Everlive) instead of having to proxy through our own server. Lets just add it from Bower.

bower install everlive --save-dev

The client OAuth flow stays the same. The developer uses Google’s script include to open the modal and ask the user to sign in. After the user has signed in, instead of dealing with a JSON Web Token, we can use the actual OAuth token since the Platform SDK is going to validate it for us.

<script>
    window.onGoogleSignIn = function (user) {
        var token = user.wc.access_token,
            el = new Everlive("5tnum1NuePyeHNwk");

        el.authentication.loginWithGoogle(token,
            function () {
                alert("Logged In!");
            },
            function (e) {
                alert("Error: " + e);
            }
        );
    };
</script>

And we’re done.

The Backend Services SDK will also do the same work for Facebook, Twitter, Windows Live and even Active Directory (for all my enterprise peeps out there).

We Can Do Better

Telerik Backend Services makes this a much less painful process. However, we still have to know which token to get, how to get that token, and how to implement it for each identity provider we want to integrate. And we have to know this for every single provider we want to integrate with, since it’s going to be different everywhere. That’s ridiculous.

This is my formal call for a proper identity solution on the web.

Why does OAuth suck? Because it’s proprietary. It’s not a standard, it’s a just a made up word that roughly translates to, “Good [bleeping] luck”.

We have got to standardize this. This is the web people. If we make this easier, it will encourage more developers to use established credential stores instead of creating more, which just increases the attack surface for hackers wishing to see your Target purchases or which dating websites you’re a member of. Personally, I’m looking forward to the day when I never have to register for another site again.

In the meantime, we have Telerik Backend Services to at least ease the pain of an otherwise nearly impossible endeavor. I hate you OAuth. Now and forever.

Grab the sample code for this article from GitHub.

Image courtesy of Daria

How to Lead, Innovate and Win in the Age of Mobile Apps

Comments

  • Pingback: Dew Drop – October 1, 2015 (#2102) | Morning Dew()

  • Jen Looper

    Preach, Burke!

    • burkeholland

      Thanks Jen! It’s the idiots guide to OAuth.

      • RJ Cuthbertson

        “The only thing worse than OAuth is the attempt by all of the
        implementers to explain to developers how to actually use it. You
        basically need to be an expert on everyone’s proprietary implementation,
        which is exactly what specifications are supposed to mitigate.”

        Yet if you don’t understand it you’re an idiot?

        • burkeholland

          Inside joke. Refers to a different article.

  • That’s pretty sheisty that social auth providers aren’t in all service tiers

    • burkeholland

      Yeah, the social auth providers integration is a top tier feature. Don’t you think it’s worth it though?

      • if you’re not going to include that in the lowest tier, you might as well just delete the whole tier.

        • Friday Dev

          I agree. It’s such a basic implementation these days it shouldn’t be considered an “Extra”.

  • 1) How does the Baas Auth SDK compare to like Auth0? (Seriously we have a Baas subscription, but we are activly looking at Auth0)
    2) Any chance you guys could implement a backend rules system like they have? So like we only want to auth users who’s email ends with a specific domain (as an example)…serverside not implement on every client.
    3) {N} PluginSample at all?

    • woloski

      1) Auth0 focus is an identity platform. It’s not fair comparing it with a BaaS which has a different focus, i.e. any BaaS has probably 5% of the features Auth0 supports related to identity. Let me name a few: email/password store, pwd policy, forgot pwd and email workflows, passwordless with sms or email, 40+ social providers plus any custom you want to implement, server side rules, user management dashboard, user metadata, user search with ElasticSearch capabilities, single sign on, multi factor authentication, anomaly detection, brute force protection, enterprise auth with SAML, AD, Azure AD and many others, an AD connector/agent that works cross firewalls, audit logs,

      2) The underlying engine of our server side rules is https://webtask.io. Basically, it’s a sandbox system based on CoreOS and Docker that let your customers write node.js code and webtask will execute it safely with guaranteed isolation and performance.

      disclaimer: I work for Auth0.

    • Anton Dobrev

      @sitefinitysteve:disqus

      1. I think that @woloski:disqus correctly outlined that both server implementations are done with different focus. The Telerik Platform may explore some possibilities to extend the existing authentication/authorization patterns in the integrated backend-as-a-service. You are welcome to submit any feedback or suggestions to the Telerik Platform team.

      2. Yet you can enforce the email of a user account to be from a certain domain with custom Business Logic in the beforeCreate event for Users.

      3. My understanding is that such efforts are already on the {N}/Telerik Platform roadmap.

      Disclaimer: I work for Telerik: a Progress Company

  • 1) How does the Baas Auth SDK compare to like Auth0? (Seriously we have a Baas subscription, but we are activly looking at Auth0)
    2) Any chance you guys could implement a backend rules system like they have? So like we only want to auth users who’s email ends with a specific domain (as an example)…serverside not implement on every client.
    3) {N} PluginSample at all?

  • RJ Cuthbertson

    One big aspect that you seem to misunderstand (or at least improperly convey to the reader) is that OAuth is not intended to be used for authentication; it is not an authentication protocol (not much of a protocol at all for that matter, but that’s another discussion). It’s only for authorization to resources owned by the provider that you’re authorizing the client with. Right on the home page of http://OAuth.net in big ol’ letters it says: “An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications.”

    There are implementations that extend OAuth 2.0 to include authentication, chiefly OpenID Connect, but that’s even more work to implement than OAuth.

    To be even more clear, http://oauth.net/articles/authentication/ states:

    “The OAuth 2.0 specification defines a delegation protocol that is useful for conveying authorization decisions across a network of web-enabled applications and APIs. OAuth is used in a wide variety of applications, including providing mechanisms for user authentication. This has led many developers and API providers to incorrectly conclude that OAuth is itself an authentication protocol and to mistakenly use it as such. Let’s say that again, to be clear:

    OAuth 2.0 is not an authentication protocol.”

    So in your opening to this article when you state “If you’ve ever had to setup authentication to one (or heaven forbid) multiple authentication providers (Google, Facebook, Twitter, Instagram, etc.), then you already know that it’s enough to make anyone want to switch careers.” that sets up the whole article around an invalid premise.

    • RJ Cuthbertson

      Just to be clear though, OAuth definitely sucks. That isn’t even debatable.

    • burkeholland

      Well, the premise of the article is that OAuth is so damn confusing, nobody can understand it. That would make the opening paragraph exhibit A.

    • Yes, absolutely. I liked it better when providers were doing OpenId. Now seems like where the hell is OpenId for all these guys, they kind of stopped doing it. Why? I would guess because they had to do oauth so they were like “let’s only support one of them since that has to be there anyway and it kind of works like authorization in a way…” or something like that. Its dumb though.

  • Chris Hewitt

    I agree, OAuth is complicated. But the main assumption, as @rjcuthbertson:disqus points out, is that OAuth is for authentication.

    This is the complicated part, in essence, you’re doing Authentication by delegation: you’re willing to delegate the Authentication process to a third party, e.g. Google / Facebook, and let them do the Authentication, you then require access to their email address (or other identifier) to confirm that the person is who the say they are.

    The complication all comes down to the callbacks & security measures:
    1) redirect user to OAuth provider
    2) user logs into OAuth provider
    3) confirm access to details
    4) redirect _back_ to OAuth client site with token
    5) OAuth client site then contacts OAuth provider with token, to confirm validity and retrieve details, e.g. email address (or try again).

    Steps 4 & 5 are the most complicated to implement, but protect the OAuth provider AND the OAuth client from highjacking / redirecting.

    Yes, it’s complicated to implement. It’s also a pain to implement, but it definitely has it’s uses.

    • Anonymous

      I totally agree with your last sentence.

    • burkeholland

      Its not the steps in OAuth that bothers me, it’s the lack of consistency between implementers.

      • I have found passport in node.js to be pretty awesome. There are these little micro followings where people have gone to great lengths to make adding new providers very simple. The same goes for email/text sending with node’s nodemailer packages so you can just snap in an email or text message provider or role your own. If you look, there are some gems out there, its not as bad as you think.

      • yea oauth is shit – use telerik oauth instead :p

      • yea oauth is shit – use telerik oauth instead :p

  • Mike Schwartz

    As Eran pointed out in his talk, https://vimeo.com/52882780, OAuth2 was kept specifically high level because OpenID Connect was the target protocol for OAuth2 authentication. Now this was clearly a disappointment to Eran, and I get it… he started with a bad authenticaiton protocol, tried to fix it, and it ended up being a nothing protocol. in many ways Oauth2 is more like a framework. However, OpenID Connect is a pretty decent authentication protocol and I think we’re starting to see a critical mass of libraries and documentation to make it easy enough for casual developers who really shouldn’t have to work that hard to identity users. That’s one of the reasons we’re developing oxd at Gluu, a standalone web server (uses jetty) that handles most of the messy messaging and gives scripters a very simple API interface. Despite some of my objections to the governance of the OpenID Foundation, I think the work that they’ve done sharing the best practices to use OAuth2 in a secure and scalabale manner is laudable. Its not perfect, but its better than SAML and OAuth1 put together. I think they achieved their goal to make simple things simple, and to also support more complex high assurance use cases. So stay tuned, things are moving slowly and getting better. The one thing we don’t need: another “simpler” protocol that will end up being insecure, or not gain enough adoption.

    • burkeholland

      Glad folks are working on this!

  • doublej42

    I don’t mind the spec but Chris is very correct. It’s better than no spec though as right now I am implementing a provider that servers oauth 2 (openID connect), telerik sitefinity auth (they came up with their own protocol and it’s not well documented), openID and SAML tokens. I’m glad that I don’t have to implement more as many clients can work in some flow with my provider.

  • This is why I created the Oauthor package to help with authentication using OAUTH2. https://www.npmjs.com/package/oauthor

    • burkeholland

      Nice! I’ll have to check that out.

      • Let me know if you find it useful. It was my humble attempt at making it bearable 🙂

  • you lose quite a bit of credibility, when you explain how bad something is, but look you can use my own companies stuff, which doesn’t suck at all.

    OAuth is a standard. You talked about JWT. i happen to do quite a lot of work with OAuth and JWT. Someone else already pointed out that OAuth and JWT is not what you use it for. It’s not for user authentication. It is there to make sure that if you have an API, no other third party tool / person / api can access it without authorization. Once that external resource is authenticated then you can allow them access to your own api which is where stuff like user authentication happens.

    You talk about going and reading some obscure forums to learn about it. Well that’s your problem right there. I found ( very quickly as well ) a Microsoft MVP who explains how these things work. I built up on his work and implemented my own JWT systems which are now in production serving hundreds of thousands of users / month.

    You are welcome to check my own article on this specific subject : http://eidand.com/2015/03/28/authorization-system-with-owin-web-api-json-web-tokens/

    I then go on to show how to use it in websites and even from mobile apps. At the end of the day, it is a standard, it’s not really that complicated, if you bother to sit down and do a bit of research ( surely not unheard of for software developers ).

    I would much more appreciate an article like yours if it did not come out as a rant. You could show both ( Oauth and Telerik’s ) side by side, showing why yours makes more sense and how it is easier to use. That would have much more value in my eyes.

    • burkeholland

      Nice article. I’ll tweet it out.

    • Henrique

      you lose quite a bit of credibility, when you explain how bad this article is, but look you can read my own article, which doesn’t suck at all….

  • SteveALee

    You missed the chance to call this post “OAuth-full” 😛

    Thanks for a great summary of the issues. I’m going to hold back for now.

  • If you don’t support the common login providers now days its like you are missing some basic thing which sucks but its kind of like the back button where you just have deal with it for the time being. I have been so tired of remaking the oath 1/2 flow so I went out of my way building an open source microservice to take care of that which I host centrally and all my apps just consume it. That approach does help a ton not having to rewrite it. There are even businesses that have sprung up charging quite a lot for providing that service because its just not fun to do.

  • Riey

    I agree with you that OAuth is more of “Hi, I have some ideas of how to make an authentication to an API service… wanna hear?”. And you can clearly know why for some APIs there’s 1 to 0 libraries for that API that is based on some other library (some general OAuth) which isn’t fun…

    I didn’t liked those libraries so I made mine for Facebook, it was fine. Then I made one for Twitter, and it took really long, I hope I didn’t had to waste time on that…

    Anyway your solution is just another lipstick on booger.

    • burkeholland

      It’s a purty booger tho

      • Riey

        You mean the lipstick I guess.

  • Chris Ismael

    Kong (open source API gateway) solves many of those problems, at least from an implementation/time prospective: https://getkong.org/plugins/#authentication

  • ashv

    Without identifying how a replacement for OAuth could be conceptually better, this reads like a long advertisement for Telerik.

  • Bish

    Great [Bleeping] Article 😀

  • rob brown

    Did you mean to make an image that says “OAUTH!!!” rather than “OATH!!!”?

    • burkeholland

      Babies can’t spell

      • remotesynth

        You calling me a baby? 😉 Sorry about that – can’t believe no one noticed before this. Fixed.

      • rob brown

        hahaha!

  • Are you using OAuth 2.0 for autentication??? Well there seems to be a misunderstanding here (http://oauth.net/articles/authentication/). Use OpenID Connect for authentication instead – it has all the properties you are asking for. But yea – nice click bait title 😉

  • Daniel

    You are looking for SQRL (Secure Quick Reliable Login). Everything wonderful there.

  • jeffsters

    As a user I REFUSE to use any of my social media credentials as a way to register for anything. I use a password manager and keep EVERYTHING separate. I don’t trust any of the above providers either not to use the fact I use a particular app, service, or make a comment to a web article. I also don’t feel comfortable having SSO across the Internet should I awake to find Facebook has been breached. Maybe I’m an alarmist tinfoil hat sounding kinda guy but I’ve never done it and even stopped using apps that made FB their only option to sign-on. Carry on!

  • Jon Forrest

    “it has it’s own Twitter account” ->
    “it has its own Twitter account”

  • seba

    SAML2 is better. Not less complicated, but better.

  • Tony Arcieri

    With a little standardization work, I think Macaroons would make a great replacement for OAuth flows: https://macaroons.io

  • I agree that the spec, libraries, and documentation are a convoluted mess. We’ve implemented oauth for our api authentication as well as social logins using FB, Twitter, and a few other sites. All of these are more or less implementing bits and pieces of Oauth 2 and more or less in a similar way, The spec reads more like a dictionary than an API specification (which is what implementers would need typically) and gives way too much freedom to implementors for no good reason at all. It doesn’t actually nail down an actual API and instead just is a tedious documenting of bits and pieces you may or may not (probably) shove into an API that it goes out of its way to not specify at all. The spec is littered with the words SHOULD and MAY (as opposed to MUST). Any time you read that, it means that somebody out there is doing it slightly different or not at all and can still label themselves OAuth complieant.

    The good news is that most of the spec is a load of horse shit that was added to keep enterprise contributors to the spec happy. They’re the reason this thing is so convoluted. Their revenue streams depend on things being convoluted so they can peddle their software and consultancy as well as ensure vendor lockin, So, reverse engineering the spec to something usable is sort of a pain in the ass. Finding a usable spec using Google is surprisingly hard due to world plus dog hogging the word “oauth” on their websites that document their craptastic flavor of it. Mostly these websites are a combination of hand wavy magic and invariably involve downloading some piece of shit library that is designed to hide the actual HTTP API from the poor user trying to figure out what messages are actually being expected or sent at which http end points.

    Once you get to the stage where you actually figure that out what needs to go over the wire it turns out implementing OAuth can actually be dead simple. It’s not something that should require a lot of libraries or documentation. Actually, I think libraries tend to add more complexity than needed and I have discarded convoluted bits of code that supposedly did something oauth related in favor of straightforward hand rolled implementations on multiple occasions.

  • Marcus Bointon

    I avoid anything OAuth like the plague. Even when it works perfectly, it’s a usability train-wreck. I think the only implementation I’ve ever seen that doesn’t overreach is github – I will not touch anything using facebook & twitter for logins. I maintain a popular library, but adding OAuth support (via libraries) has nearly doubled the amount of code in the lib, and the result is mostly unusable – when everything works properly, it will probably take an hour to get a login working, vs the few seconds it takes to use an id and password. The supposed improvement in security is a myth – at some point you’re going to have to transmit an id and password over TLS (especially given the frequency with which fb and twitter lose track of who I am and I have to log in again), so the security it offers is no better than that, and the massive complexity of configuring it just means it’s more likely to be done wrong. Even if the standard was consistent across providers, it would still be horrible.

  • Onion ID Anirban

    I do resonate with the pain. Yes, Oauth is not easy to grapple with and whatever happened with OpenID not catching on more is clearly bad for Authentication. Multiple vendors deciding to add their own flavor on things is a real issue. Even for SAML based logins we have had to implement modifications for some specific private applications developed by enterprises. Although the same problem in the SAML space is smaller by comparison (in my limited experience). For discussions with customers we try to keep them true to as close to specs/standards.

  • Pingback: The Radar: November 11, 2015 | Objective Blog()

  • Reddy Bimwala

    “I’m looking forward to the day when I never have to register for another site again.”

    This day will never happen, and it won’t be because of OAuth.

    In his comment below jeffsters has a point. I think you overlook the fact that end-users in B2C scenarios are not fans at all of this single sign-on trend. OAuth is much more appropriate for enterprise scenarios, where a company wants to have a single user stores for all its applications and grant permissions to access the apps in a centralized manner.

    B2C users are more comfortable keeping all their data separate. I haven’t met yet someone saying “Hell Yeeeea”, when facing a “Log In With Facebook” button. More commonly the user stares at the “The application requires the following permissions” screen, and wonders if things will be posted to his wall.

    The people who really want Single Sign-In are application developers, that’s the only reason we see it in many places. Users never asked for that. And application owners like it not because it makes authentication easier – it will most of the time be more difficult than adding a row to a Users table. They like it because the prospect of having access to more info about the users than they’d be willing to fill in our app, as well the proximity with their social graph are appealing.

    Personally for many reasons I decided to never ask my customers to log in with OAuth.

    That being said, in terms of OAuth I think ASP.NET Identity does most of the heavy lifting for you these days…. I’d agree that OAuth might look daunting, but the OAuth inconsistencies are largely abstracted from .NET Developers – I was surprised to read that you are one. I would have expected this rant to come from someone not using Microsoft’s stack.

  • Pingback: Denny Figuerres Software and stuff | A post i found on Oauth()