You’re feeling some pains, so you go see a doctor. The doctor sends you to have some tests done at a lab on the other side of town. The results come in a week later and you have to get those results into your doctor’s hands. You could just go back across town and get them, but that’s a pain. It would be much easier if your doctor could get the results directly from the lab. It would be even better if they could be transferred digitally.
But now we run into problems of security. What if someone else calls the lab impersonating your doctor and gets your test results? What if you change doctors and the lab releases the test results to your old doctor against your wishes? What if the lab is full of jerks and they send all sorts of crap to your doctor in your name. We have this exact same problem on the Internet, and that is why OAuth was created.
For decades the most popular means of authentication on computers has been usernames and password combinations. You want to prove to some system that you are a certain person, so you enter in a secret piece of information that only you know to prove you are you. Now that you have identified yourself the system will allow you to engage in activities permitted to your account.
Now let’s say you have a newsletter system, and you want it to send out emails on your behalf. Even to this day a very popular way of doing this is to give the newsletter system the username and password to your email account. The newsletter system will authenticate on your behalf, so your email server will think that the newsletter system is you. That’s what authentication is all about. As far as your email server is concerned the newsletter system is you, and has permission to do everything you do, including changing your password or deleting your account.
It’s obvious that this is a problem. Even though that goes against everything you’ve ever learned about security and passwords, people still do things this way. You should never tell your password to any other person ever, not even your closest and most trusted people like spouses. You definitely shouldn’t tell it to other computer systems. You should only ever send a password to the system for which it is intended. Your email password is for you, your email server, and that’s it.
Well, I made this fun game on the web, and my users want to tweet out their high scores. I could just suggest they do it with copy/paste, but that’s like driving back and forth across town to get the test results. Instead, I want my game to do the tweeting on behalf of the users for the greatest efficiency. Now I could, and many systems did, just ask for the users to give me their twitter usernames and passwords. It is possible I could be honest and not abuse that, but do you trust me? Even if I was an entirely client-side application, and your password is being sent directly to Twitter, this game is not officially endorsed by Twitter. How do you know I’m not secretly sending your password to my own servers or doing something else shady?
Thankfully we have solved this problem, and the solution is OAuth. OAuth is slightly complicated, but it gets the job done. Let me explain it as simply as I can using our high score game tweet example. We’ll call the game shootyguy.
You have a Twitter account, and I want you to let shootyguy send tweets on that account. First shootyguy gets its own special twitter application account. That account has an ID and a secret, which is basically the same as a username and password. Now shootyguy can authenticate with Twitter and prove that it is indeed shootyguy.
When you get a high score for the first time it will give you a link saying “click here to let me send tweets for you!” That link is a link to Twitter. It contains shootyguy’s ID number and a list of the things shootyguy wants you to let it do. In this case the game is only asking permission to send tweets, but it could also ask permission to edit your avatar, change your profile, etc.
You click on this link and you are sent to Twitter itself. It’s safe to give your Twitter password to Twitter, obviously. You do so, and Twitter asks you, “Hey, do you want to let shootyguy do the following things with your account?” If you say no, nothing will happen. If you say yes, then Twitter will remember that shootyguy has permission to send tweets for you. It will also send shootyguy a special secret password that it can use to act on your behalf. If shootyguy is a popular game, it’s going to have to remember those secret passwords for every user who has tweeting enabled. As long as the game holds onto these secrets, and you don’t take permission away from it, it won’t have to ask permission again. This painful user interface problem of jumping back and forth between web sites only has to happen once ever.
This is what is called authorization. You see, both you and shootyguy authenticate with Twitter to prove you are who you say you are. You are authorized to do whatever you want with your own account. Shootyguy is authorized to send tweets, but nothing else, on a whole bunch of accounts that have granted it permission. Up until relatively recently we didn’t have authorization, just authentication. Now that we have it, it’s easy to see why it is so incredibly important.
Perhaps the most important feature of authorization is the ability to deauthorize. Imagine if shootyguy got hacked like the PSN and it had a database full of Twitter passwords. That would be extremely bad. You would have to change your password before hackers started using it. If they had used OAuth, you could just remove authorization for the compromised application, and your account would be perfectly safe. Worst case the hacker starts doing the few things you authorized them to do before you turn them off.
I think I have made it very clear that in cases where you want to give a third party access to one of your accounts, OAuth, or a similar authorization system, is an absolute necessity. Anything less is grossly negligent.
Given that, what is up with the title of this blog post? Shouldn’t it be “Always OAuth”? Well, that seems to be the opinion of many sites out there such as Twitter and Facebook who are forcing OAuth as the only way to interact with their APIs. I can see why they do this. OAuth is more complex to implement, so developers would keep taking the easy way out by collecting passwords if they were not forced to use OAuth. It’s also next to impossible to educate users on not giving out their passwords.
Yet, there are still those rare occasions when OAuth becomes a huge pain in the ass for no benefit whatsoever. Let’s turn the tables around a little bit. Let’s say that we make an official shootyguy twitter account. We want to automatically tweet on that account whenever a player beats the game at shootyguy.com. How does that work?
In this case, we don’t need to ask the player for authorization. We aren’t using the player’s Twitter account. Shootyguy is using its own account. There’s no benefit to using OAuth in this case. It would just be easier for shootyguy to authenticate with its own username and password, and have full authorization to tweet with its own account.
The problem is that shootyguy is a program, not a person. It can’t just visit twitter.com and send a tweet. It has to use the API to tweet programmaticaly. But the API forces you to use OAuth no matter what. Since it is a program, and not a person, how can it click the “Allow” button in the browser? It can’t. What you have to do is manually do the OAuth in a browser and collect and save all the secret keys along the way. Then you put all the secret keys on the shootyguy.com server so it can send tweets.
Is it really that hard? No, there are many things that are more difficult, but it’s still a pain. In a way it makes sense. The shootyguy account is giving permission to the shootyguy.com application to tweet on its behalf. But Twitter is actually pretty simple as far as OAuth goes. If you want to see frustration, try it with Facebook.
Pretend that instead of posting to a shootyguy twitter account, we want to post onto the wall of the official shootyguy Facebook page. Well, a Facebook page isn’t a Facebook account, or is it? And a Facebook account isn’t a Facebook app. I’m going to write a tutorial on every step involved in doing this, but here’s the TL;DR version. You have to create a facebook account, a page, and an application. You have to authorize the account to post onto the page. Then you have to authorize the application to have a bunch of permissions on the account. Then the application has to use its secret keys on the account to get yet another secret key it can use to access the page.
Again, this is actually a great system when you are using it for what OAuth was designed for. If you want to give the game permission to post on your personal Facebook wall, this is fantastic. For the game to post on its own Facebook wall this is awful.
Of course, my complaining isn’t for naught. I actually have a solution that doesn’t require changing OAuth itself in any way. The solution is actually quite simple, and it actually opens the door to more features for users that have been unexplored.
I won’t hold back, the answer is to make every account also an application that has full authorization of itself. Why are applications and accounts separate entities? Why do I have to make my own Facebook application and connect it to my account? If my account were also an application, it would only need authorization to do things with other accounts, but not as itself. I shouldn’t have to pretend to be an authorized third party application to post on my own personal Facebook wall through the API.
One side benefit of this is that every user account can be authorized to perform actions on other user accounts. That can be dangerous if people give too much authorization away, but I think it will be very clear to people what is going on. “Do you want to give your friend joeyjoejoe1337 the ability to edit your profile? Yes or No?” It’s not a question too many people are going to get wrong.
While you may not immediately realize it, there are many cases where people will want to say yes. A parent can give their children their own personal private accounts, but can then authorize their own accounts to have a certain amount of access. You could authorize your trusted friends to handle your accounts in case of emergency without giving anyone your passwords. You could have a company account and give many people access to it without sharing a password around the office. You could then easily add and remove authorization as employees come and go. There are many duct tape third party systems that add this functionality for businesses that could be done away with completely if my idea were implemented.
I hope from reading this that you have a good conceptual understanding of the difference between authentication and authorization. I also hope you understand what OAuth is, why we have it, and why it is so great. And though I know it won’t change anything, I just wanted to complain about the unnecessary complexity that can make OAuth sucky under certain circumstances. If you are building an application, make sure you use it appropriately, and please try out my idea of every account being an application. And remember, never ever give your password for anything to absolutely anyone at any time under any circumstance. It is never necessary. No, not even in that circumstance you just suggested.