Hacker News new | past | comments | ask | show | jobs | submit login
The OAuth chronicles: I am not stupid (ashfurrow.com)
78 points by moeedm on Dec 2, 2011 | hide | past | favorite | 61 comments

He's right. OAuth does suck. Thankfully OAuth2 sucks less... a lot less. We're working on an API now, and only plan to support OAuth2.

As far as the iOS side of things, the OAuth2Client library by nxtbgthng has worked amazingly well for us: https://github.com/nxtbgthng/OAuth2Client

I hadn't seen that. It looks really promising - thanks!

I haven't worked much with OAuth on the iPhone, but what I hate is that, when it's embedded in apps, it makes phishing attempts pretty much undetectable for end users. I see a Facebook login form pop up in a UIWebView in an app - is it really Facebook, or is it some other site? I have no way of knowing.

There was a big thread on the OAuth mailing list about this a couple of months ago. The official response seems to be "don't use native applications that you think might phish you", which isn't very satisfying.

I'm not sure what the alternative is, though, and OAuth is still a big improvement for the web app client use case.

As an Android developer who's been struggling to get OAuth 1.x working for the past few weeks in his spare time, I wish I could say it's any better on this side of the pond. We have some marginal improvements since we can register our own app to be the receiver of the OAuth callback (using Intents). But it's still excessively complicated.

Last summer I had some issues getting OAuth working with the Twitter API for Android apps. I ended up using the signpost library. I posted my results with instructions here: https://github.com/adelevie/AndroidOAuth. Maybe it will help you.

Similarly here https://github.com/vitalius/Twiturr/blob/master/src/com/twit...

I also find using WebView activity for launching twitter authentication page is more robust in terms of controlling activity focus.

Thanks, I'll definitely take a look. My issues now mostly stem from attempting to integrate the OAuth solution that I have working into the SyncAdapter / ContentProvider abstraction that Android provides.

OAuth (even two) sucks - and not just at the implementation level. OAuth will continue to suck until it adheres to the laws of identity.

Unfortunately the alternatives look pretty bleak too. If you want to use identity federation, you're stuck with WS-* (you need the active requestor profile for thick clients), and, more fundamentally, you need an identity provider (IDP). Note that Facebook, Google and Twitter don't count - they're not justifiable parties except unto themselves.

Once you get the IDP sorted you have more options. You can use U-Prove or IDEMIX to provide anonymity, derived claims (proving you're over 18 without divulging your age) and discretionary access to claims.

Problem with all of the above is that identity selectors aren't as mature as they could be (CardSpace has been abandoned by Microsoft, and the Higgins Project doesn't have an adequate solution for putting information cards onto, say, a smart phone).

Given the sorry state of identity today, I've created my own framework which required close to 10K LOC (client and server).

It's an insane world. We still haven't managed to come up with anything better or more usable than user name and password.


You can just look at all the various revs and options that OAuth has and know that they are casting around for a correct answer.

I've implemented two oauth 1.x handshakes and both were full of one-off complications and incomprehensible error states.

I'll take a look at OAuth 2 when it becomes more prevalent, but until then no why in hell I'm moving away from a simple "generate an API key" approach.

Everyone chiming in here is just blatantly, blatantly wrong. OAuth is a solid solution to a very real set of problems.

The fact that you are unaware of the potential problems does not make those problems any less valid.

As someone who has implemented an OAuth flow on Android and iOS, I can agree that it's not easy. But it does solve a serious set of security issues which are raised by having a third party act on behalf of a user. Not only does it permit more fine grained grants to applications that the user trusts to varying levels, it allows a compromised application to have all of its keys invalidated at once. It allows a user to disable a single misbehaving application's access to their account. These are prices worth paying.

Learn what you're whining about. Then deal with it.

Not quite sure which (or who's) whining you're having a go at, but as an identity system OAuth is indeed a pile of poo.

First, OAuth1's poorly-spec'd signatures make implementation difficult. That's an accepted and pretty well-documented fact.

OAuth2 removes all crypto and instead relies on bearer tokens and SSL/TLS, while not mandating it. It does away with signatures in favour of ease of implementation. [edit] This is a bad thing.

OAuth2 is also susceptible to man-in-the-middle attacks where a malicious party could gain access if it intercepts a token.

That's a pretty poor implementation.

As an identity provider OAuth 1 and 2 have problems beyond the technical interpretation of the specs, or implementation difficulties. Both fail as an identity system (ref. http://www.identityblog.com/stories/2004/12/09/thelaws.html).

I'd love to hear why you think OAuth is a solid solution.

My primary gripe is with people claiming that oauth doesnt solve a problem. That simply providing a single header is all that is requited. That OAuth is too hard.

OAuth is a set of flows for obtaining tokens. These toekns are, by definition, bound to an application-user grant.

The rest is implementation details.

Which flow are you referring to as being succeptible to mitm attack?

I would also love to hear why you think that identity has anything to do with OAuth or this discussion.

OAuth is an authentication mechanism, meaning it implements a principle of logic stating that a subject is who he/she claims to be (authN), and then asserts that to a relying party (authR). In other words, OAuth establishes identity.

Your question about MITM is answered at http://www.subbu.org/blog/2010/09/oauth-2-0-and-cookie-conve....

OAuth is not an authentication mechanism. It's an authorization mechanism. This is the source of your confusion.

OAuth is a mechanism by which an application can be granted authorization by a user to another application.

The identity question is not in any way addressed by OAuth. It is up to the application implementation to handle identifying the user creating the grant.

The link you provided basically establishes the same problem which is always the case - if someone is watching your (unencrypted) traffic, you're hosed.

That authorisation is an assertion of identity. This makes OAuth an identity system inasmuch as WS-Federation and the SAML protocol are identity systems. Technically they're parts of an identity system, making them identity meta-systems.

Maybe, but that has nothing to do with OAuth. One could be completely within the OAuth spec and allow one user to provide grants to act as dozens of other users. You are basically saying that OAuth is not good at something it was never designed to have any say about.

It's as though you're saying that your rolling pin doesn't work well as a meat tenderizer. Yeah, I guess they're related, but that's not what a rolling pin does.

Of course you're right. I'm an idiot. Thanks for setting me straight.

OAuth2 isn't just about bearer tokens and while the OAuth2 spec doesn't mandate using TLS the bearer token sub-spec does.

OAuth 1 is hard. OAuth 2 is much easier.

But OAuth 2 still sucks on native apps. The spec strongly discourages storing keys in the application binary, but every single mobile app example I see does this. My question: is anyone doing this _right_? How?

Storing app keys? You have to store some sort of key in the binary.

This is all it took for me to implement Tumblr's API with OAUTH on Android 1.6 and up: https://github.com/RobertSzkutak/AndroidExamples/blob/master... . I've personally never had a problem working with OAUTH (1.0 or 2.0) on Android. Does iOS development really complicate writing clients for web services that much more?

This is such a ridiculous post from someone who got frustrated because they didn't understand OAuth. Nothing more. They will get it soon, and they will feel bad for attempting to write something that makes OAuth look bad. Give it time.

No, it's that simple on iOS too if you pick a sane OAuth library.

I just need to add my voice to the chorus: OAuth really, really sucks.

I don't understand what problem it solves. A malicious app (native or web) can find a way to get your password, period. A well-behaved app can have your password and do no harm. And, practically speaking, I don't know any real person who's had a problem that has been solved by the existence of OAuth.

OAuth is just a massive pain in the rear end.

The "ideal" is to give the app permissions akin to another account. This way the app only changes what the user says it can change, etc, even to the point that users can upgrade or downgrade these permissions later.

The most obvious advantage is the app doesn't have to learn the users new password when they change passwords.

But you're right, the whole dance of having the app never `touch` the user's password is bullshit, a pretense cooked up by bureaucracy. You could get all the meaningful functionality of Oauth by letting apps request a single "permission key" when they login - with the user's password. On the other hand, if a site want real, meaningful security, it could give each user a seperate "app password" that they authorized apps with. That would provide real protection - but since it requires one teentsy extra step for the end user, it will never, ever fly.

> You could get all the meaningful functionality of Oauth by letting apps request a single "permission key" when they login - with the user's password.


> A well-behaved app can have your password and do no harm.

Until someone steals its database.

You hash your user's passwords, right? Same thing - whether you're talking about your app's passwords, or some 3rd party app's passwords, keeping them around in plain text is a bad idea.

And hashing them is not useful if you intend to authenticate with them. I think you mean encrypt. Hacker finds encryption key. See "Until someone steals its database."

No, that's not what I meant. It's an analogy - if sites shouldn't store their own passwords in plaintext or reversibly encrypted (which everyone here agrees on - "use BCrypt", etc), then they shouldn't store other passwords in plaintext or reversibly encrypted. They should use something like OAuth instead.

My bad, we agree on this. But there are a whole bunch of other great things that OAuth brings.

I must not have been very clear, because I'm being pro-OAuth here :)

Not familiar with OAuth, but the concern about NSURLConnection seems a bit silly. Create an NSObject subclass, give it a NSURLConnection and a block ivar. Set it as the delegate of its own NSURLConnection. Setting up a "store" object that handles the preparation of NSURLConnection instances is also useful. Have the store keep track of all working NSURLConnections (which gives you the ability to cancel easily, too).

If you are using NSURLConnection out of the box and writing the delegate methods over and over again in every view controller or store object, you are doing something wrong.

This article doesn't say anything about whether OAuth, the authentication protocol, sucks or not. It's referring to current OAuth libraries for iOS.

Server side OAuth is easy to implement, even without any library: you just send login parameters and callback-url where you get actual token that can be used to authenticate user. Problem with natice client is that, well, you cannot give callback url that will always work (having http-server at client? clumsy, hotspots will block, etc.).

Only way (even with OAuth2, if I recall right Google documentation) to get "working" flow with natice apps is to give special parameter as callback-url, which will return validation token in html-page. From where you need scrape it. Maybe there will be something better after OAuth2 is finished, but for now: easier to make own authentication server and API to talk with it.

There's a reason the client libraries are lacking though.

In my experience with both OAuth 1.0 and 2.0 libraries for iOS, Node.js, and Ruby (among others), OAuth 1.0 is just a lot harder to implement. It's not fun in any way...

But that "X Sucks" title sure gets the hits...

This article reads more like "XAuth sucks". I've done more Windows Phone dev than iOS dev - and apparently I've taken the "native code listening for a Javascript event" functionality for granted. OAuth via a web view is dead simple.

You can do this in iOS and Android as well.

Correction, OAuth < 2.0 sucks. OAuth2.0 is actually easy to use and more secure.

There is no reason to use OAuth ever, in any shape, under any circumstance, which is a bad for the tech but (in this case) good for everybody else.

Instead of using the bloated OAuth multiple requests back and forth, permission keys, auth keys, consumer secrects, etc, etc. you can simply add an additional header saying "client id" which the service provider can then use to "secure" his er her service as he sees fit.

OAuth is a bloated attempt to paper around the simple solution so that the astronaut architects who made it can feel smug about themselves.

OAuth solves no problems, helps nobody and has (drastically) polluted our ecosystem. To hell with that shit.

> you can simply add an additional header saying "client id" which the service provider can then use to "secure" his er her service as he sees fit.

OAuth 2.0 is basically that + a standardized protocol for requesting a "client id", which is why it's completely insecure over standard HTTP.

Thats why OAuth2.0 protocol is limited to HTTPS and is said to never be implemented over HTTP.

Except the client id has to be generated so that you know which client was authorised with it - in the case of something like Facebook or twitter, so you can revoke their access.

That means you have to agree on a way of exchanging that client ID.

Which at it's simplest is what OAuth 2 does with bearer tokens. If you have no use for the other parts of the spec then just ignore them, it's all optional and you only need to implement it if you need it.

Sounds like your saying, "Don't use OAuth because it's bloated, create your own API auth protocol and make everyone use that non-standard protocol for my API". That forces developers to implement "custom" protocols per API that may actually be worse than OAuth.

You must not be developer. OAuth 2.0 is not bloated and pretty much 2 steps with a clause to never use it via HTTP. How could it be more simple?

Can you explain how would that work?

nope, oAuth 2 is still a pain to use. all of the oAuths are developer hostile, they make authentication a many step process with many potential fail cases.

OAuth 2 a simple two step process:

1) Redirect the user 2) Do a POST request to acquire an access token

How is that a pain?

And to be pedantic, there's a third step:

3) When you make an authenticated API call, send the access token along with the request, and make sure you're using HTTPS.

The HTTPS part is important to give a bunch of the security guarantees than OAuth 1 gives you with plain HTTP and some complicated crypto dancing around.

The problem with OAuth1 was that the complicated crypto dancing around was exactly that, complicated. Making sure you're using HTTPS is hardly a big ask for developers on either the client or the server and frankly is probably a much better idea given most of these services are more likely than not sending some form of private data.

Agree. Had a hell of a time getting OAuth to work on my iPhone Netflix app. Just hours and hours wasted.

I have an Instagram iPad app which was a breeze to implement. IG does a great job documenting their API.

Asynchronous comm doesn't need to lead to spaghetti code, but it certainly will if you don't know how to organize it.

More like spaghetti code, then. dispatch_async() with NSURLConnection's synchronous method is way cleaner and faster to build an app with than NSURLConnectDelegate callbacks and holding onto the reference of multiple NSURLConnection instances.

It's possible to organize your code using asynch methods, but considering Apple's move toward block-based APIs, that's what I choose to use when architecting the apps I write.

Apple's block-based APIs aren't intended to replace asynchronous APIs. In fact, Apple's block-based APIs ARE asynchronous APIs. Half of the intent of GCD is to provide a dynamic-thread-queue asynchronous interface to non-blocking I/O APIs via kqueue and friends.

GCD aside, there are a ton of reasons not to use synchronous networking, from the resource costs (you're paying for a thread stack per request) to the inability to cancel the synchronous request.

One of Apple's engineers (Quinn) wrote up a whole post on the dev forums about why you should not use synchronous networking. It's a "sticky" post at the top of the iOS->Core OS forum:


Lastly, I think your position on spaghetti code is misguided. A block-based wrapper on NSURLConnection will be just as simple as dispatch_async().

It's also less portable, pluggable, testable...

The big problem with oauth is how inconsistent everybodies implementations are. There isn't a good library because there are so many edge cases where API's implement it differently.

It's a developer hostile mechanism, but unfortunately it's the best option out there for granting subset access to an API with easy token revocation.

The reason is OAuth1 is painful, the double encoded and signature requirements are strict and so easy to get wrong that everyone has jumped on OAuth2. Unfortunately they've all jumped on different versions of the spec which keeps changing , because it's still a draft.

Started skimming the article and my eye fell upon this:

> If you want any meaningful error messages, you need to opt for the asynchronous URL connection methods. Why does that suck? Because it takes a really easily architected, synchronously-called API layer that is run in a background queue with Grand Central Dispatch and turns it into a bloated, complicated asynchronous pile of spaghetti code.

Sorry, dude, but you definitely are stupid. You're seriously advocating tying up an entire OS thread purely to do synchronous network IO. That's incredibly stupid. It's pretty trivial to throw asynchronous network IO onto a worker thread. You're still using a thread, but now you can multiplex _all_ of your IO on to one thread instead of using one thread per network call.

FB and IG are OAuth 2.0.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact