6

I'm writing a RESTful service (Java EE, Jersey) and a client application that communicates with it, and I wish to secure it and store any usernames & passwords dedicated in my own database.

I do not want the client to store the username and password locally, not in any form such as base-64 or other encoding at all, I rather have something like the OAuth2 authorization system, where the client app only stores a refresh & access tokens after the resource owner signed-in, but I do not need to provide access to 3rd party services.

Securing my service using Basic auth means the client app has to store the password and send it for each future request, so that's not what I need.

I'm aware that OAuth is intended for different situations, where there are more than just 2 parties involved (see other question).

as mentioned here https://blog.apigee.com/detail/when_to_use_oauth: OAuth is the only realistic choice for a web application that itself uses another web application's API on behalf of the user. For instance, consider a web application that integrates with Twitter. (Perhaps it's a geolocation app like Foursquare that offers the ability to tweet where you are and what you're doing.)

So what is the correct standardized method to secure my RESTful service if I do not wish to re-invent the wheel and create my own auth method, and if "Basic" is not what I need because it forces me to store the credentials locally on the client, and OAuth is probably an overkill with it's 3rd party access nature.

P.S- I do wish to provide users with an option to sign-in to my service using facebook or open-id, but that's another story I guess.

3

You can very well use OAuth 2.0. OAuth gives you various grant_types to support various use-cases. The use case you have will have grant_type = password, this is a 2 Legged flow, unlike the 3-Legged where there are 3 parties involved, ie.

resource_owner (enduser)
Client (third party app)
Resource server (Server)

as Server & your mobile application belong to same trust group, you should use 2 Legged OAuth (grant_type=password) general flow is

POST /oauth/token
Authorization: Basic base64Encoded(<client_id>:<secret>)
username=a&password=b&grant_type=password

This shall return you with access_token and refresh_token.

2

I had a similar problem a couple years back, and I found this article to be incredibly helpful.

http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

The basic idea is to have the client and the server to have a shared secret. That shared secret is never communicated over the wire, but is used to create a token (HMAC) that verifies the request. The client does need to know the algorithm for creating the HMAC (can be provided via a client library) and a secret (similar to a password, but not a password).

In your question you mentioned that you don't want your client to have to store the password. This solution does require the client to look up the secret, so it may not meet your requirements; however, it does not require the client to authenticate or sign in to your service.

(On a side note, you mentioned storing passwords as base64. Never store passwords as base 64. Encoding is not the same thing as encryption.)

  • 1
    That's a good article, but at the end he says, "I have since looked at '2-legged OAuth' and it is, as a few readers pointed out, almost exactly the process described above." In essence, he did a great job of running through re-inventing OAuth 1 ;) I'm not knocking him, just pointing out that the OAuth specs (1 & 2) are really thorough, and if you implement your own protocol, as you add stuff to address security concerns, you end up with OAuth. The main difference between OAuth1 & OAuth2 is that 2 removes hashing and defers the cryprographic stuff to SSL. But libraries for 1 are still around. – Rob Jan 8 '15 at 14:28
2

Oauth (not sure about Oauth2) gives 3rd party access to resources using combination of consumer key and access token. So, for 2 party communication, you could bend it to only use consumer key without (or empty) access token. This will only give you a way to authenticate requests by using Oauth Authorization header.

Then, what you use as consumer key is up to you. It could be as simple as using user id as consumer key and user password as consumer secret, so you won't have to store them anywhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.