2

After a real brain bending session today I feel like I understand 3-legged OAuth authentication fairly well. What I'm still having trouble understanding is the use of the User ID. The examples I have seen so far all seem to just arbitrarily assign a user ID at the top of the sample script and go. That confuses me.

Most of the sample code I have seen seems to center around the concept of using a user ID and the OAuth server's consumer key for managing an OAuth "session" (in quotes because I'm not trying to conflate the term with a browser "session"). For example, the database sample code I've seen stores and retrieves the tokens and other information involved based on the user ID and consumer key field values.

I am now in that state of uncertainty where a few competing fragments of understanding are competing and conflicting:

1) If my understanding of the OAuth session details record or "OAuth store" lookups is correct, via the consumer key and user ID fields, then doesn't that mandate that I have a disparate user ID for each user using my application that connects with an OAuth server?

2) If #1 is correct, then how do I avoid having to create my own user accounts for different users, something I am trying to avoid? I am trying to write software that acts as a front end for an OAuth enabled service, so I don't need to have my own user records and the concomitant maintenance headaches. Instead I'll just let the OAuth server handle that end of the puzzle. However, it seems to follow that the downside of my approach would be that I'd have to reauthorize the user every session, since without my own persistent user account/ID I could not lookup a previously granted "good to revoked" access token, correct?

3) What bothers me is that I have read about some OAuth servers not permitting the passing of a dynamically specified callback URL during the requesting of the unauthorized token, making the passing of a consumer key and a user ID back to yourself impossible. Instead you specify the callback URL when you register as a developer/consumer and that's that. Fortunately the OAuth server I'm dealing with does allow that feature, but still, if I was dealing with one that wasn't, wouldn't that throw a giant monkey wrench into the whole idea of using the consumer key and user id pair to index the OAuth session details?

Robert Oschler
  • 14,153
  • 18
  • 94
  • 227

2 Answers2

2

This is an answer to the question by Lode:

Is it correct that not only the provider needs to have user ids (that sounds logical) but also the client? So the client (using OAuth as a login system) needs to create a user (with an ID) before successfully authenticating them via the OAuth server. Making you have a lot of empty user accounts when authentication fails or access is not granted.

It's possible to use OAuth for authentication of users without having local accounts at the consumer application, but you've got to have some kind of session mechanism (cookies/get params) in order to have some internal session representation in which you would store the oauth_token.

For example, if someone has landed to your web application, and your application is a consumer of some OAuth provider, you will have to create a local session at your site for the end-user: for example with a cookie. Then you send the end-user to the OAuth provider for authorization of a token, so that your application can get protected resources from the provider. Currently you know nothing about the user and you don't care about his identity. You just want to use some protected information from the provider.

When the user comes back from the provider after successful authorization and brings back the oauth_token, you now have to store this token in the session that you previously created for the user. As long as you keep your session (and the token if it's needed for further requests for resources), you can consider that the end-user is logged in. In the moment that you delete his session or the token expires, you can consider him no more logged-in. This way you don't have to make your own users DB table or storage mechanism.

However, if you need to have some persistent information about the users in your application, that will be used between user sessions (logins), you have to maintain your own users in order to know with which user to associate the information.

As for the difference between openid and oauth - from the perspective of local accounts, there is no difference. It's all the same. The difference is only that with openid you receive immediately some basic user info (email, etc.) while with oauth you receive a token and you have to make one more request to get the basic user info (email, etc.)

There is no difference however in regard to local accounts, if you're going to use OpenID or OAuth.

Community
  • 1
  • 1
luben
  • 2,512
  • 4
  • 30
  • 41
  • Thanks for the clarifications. Am I correct that I don't really need the session either as the OAuth provider/server sends the user back to me using the same request token as I sent away? Also, I don't really care about the user before I get his information. So, when I get the info I consider the user at hand at that moment to be the owner of the information and create a local account for her. Before that moment, I don't have anything to keep track of right? Or is it more a matter of security to track the user in this process with a session? – Lode Aug 30 '12 at 19:19
  • Hi, you will need a session, because you will not be able to understand from which user the requests are coming - unless you put the oauth token in the URL forever, so that the user is always coming back with it (like a session id). Which version of OAuth are you planning to use - 1.0a or 2? – luben Sep 03 '12 at 08:56
  • I'm using 1.0a. As for the session, each time a user connects using OAuth, we get their email address (after authorization). So that is a way to check who the user is. Right? – Lode Sep 03 '12 at 09:07
  • Yes, when you get email you can distinguish users. I was wondering however, how do you keep track of users after you have received their email - for example, when the user is browsing your site after authentication/authorizaiton, how do you distinguish users if you don't have local session implementation? – luben Sep 03 '12 at 09:40
  • 1
    Ah sorry. Yes, I do have a local user and session management. It's just that people coming via OAuth are not known before I get their email address. After that, I'll create a user for them if they are unknown, log them in and track them using sessions. But I don't use a session before I got their email and turned them into a user. – Lode Sep 03 '12 at 10:05
1

I will try to tell my view on the issues that you raised and hope that will clear things a little bit...

First, the idea is that the OAuth server is protecting some API or DATA, which third party applications (consumers) want to access.

If you do not have user accounts or data at your API behind the OAuth server, then why would a consumer application want to use your service - what is it going to get from you? That being said, I can't imagine a scenario, where you have an OAuth server and you don't have user accounts behind it.

If you just want to use OAuth for login of users, without providing user data through API, then it's better to use OpenID, but again you will have to have user accounts at your side.

Your point is correct that you make lookups via Consumer Key and (Your) User ID, and that is because of the protocol design.

The general flow is:

  1. OAuth server (Provider) issues unauthorized Request Token to consumer application
  2. Consumer sends the end-user to authorize the Request Token at the OAuth server (Provider)
  3. After end-user authorizes the token, an access token is issued and given to the consumer (I've skipped some details and steps here, as they are not important for what I want to say, e.g. the consumer receives valid access token at the end)
  4. On the authorization step, it's your OAuth server that create and save as a pair - which local user (local for the provider) authorized which consumer (consumer key-user id pair).
  5. After that, when the consumer application want to access end-users DATA or API from Provider, it just sends the access token, but no user details.
  6. The OAuth server (Provider) then, can check by the token, which is the local USER ID that has authorized that token before that, in order to return user data or API functionallity for that user to the consumer.

I don't think that you can go without local users at your side, if you are a provider.

About the callback question, I think there's no difference if you have dynamic or static (on registration) callback URL in regard to how you handle OAuth sessions with consumer keys and user id. The OAuth specification itself, does not mandate to have a callback URL at all - it's an optional parameter to have, optional to send every time, or optional to register it only once in the beginning. The OAuth providers decide which option is best for them to use, and that's why there are different implementations.

When the provider has a static defined callback URL in the database, connected with a consumer, it is considered a more secure approach, because the end-user cannot be redirected to a 'false' callback URL.

For example, if an evil man steals the consumer key of a GreatApp, then he can make himself a consumer EvilApp that can impersonate the original GreatApp and send requests to the OAuth server as it was the original. However, if the OAuth server only allows static (predefined) callback URL, the requests of the EvilApp will always end at the GreatApp callback URL, and the EvilApp will not be able to get Access Token.

luben
  • 2,512
  • 4
  • 30
  • 41
  • 1
    You're right. I'm going to end up with at least a user ID and PIN. Good point about static callback URL security. One question. You say "if an evil man steals the consumer key of a GreatApp", but wouldn't they have to have the secret too? I hope so because I've seen sample code where they suggest passing it back to your callback URI as a plainly visible GET url argument. For example, see the section titled "Step 3: Obtain Access To A Server" in the oauth-php sample: http://code.google.com/p/oauth-php/wiki/ConsumerHowTo – Robert Oschler Apr 20 '11 at 13:51
  • Yes, you're right, I should have said consumer key and consumer secret, because only with the key alone, not much can be done :) – luben Apr 21 '11 at 06:07
  • @Lyuben, is it correct that not only the provider needs to have user ids (that sounds logical) but also the client? So the client (using OAuth as a login system) needs to create a user (with an ID) before successfully authenticating them via the OAuth server. Making you have a lot of empty user accounts when authentication fails or access is not granted. That makes it hard to use OAuth as a login system, OpenID is better then. – Lode Aug 27 '12 at 14:58
  • Hi Lode, it is possible to use OAuth as login without having accounts at the consumer application, although that is a case which is not very usual, however I'll need more space to explain it than the comment - do you think I can add another answer for this here? – luben Aug 28 '12 at 07:39
  • @Lyuben, if you have more info / explanation on it, I would love to hear. I think editing your existing answer works just fine for that. As far as I read the question it is about this issue as well. – Lode Aug 30 '12 at 19:13