4

I have found numerous academic answers to this question, but I would like one from practitioners in the field.

Background

I would like to create a Java-based RESTful API, using the Grails framework for a variety of mobile clients (iOS and Android) to access protected resources through my service. I require authentication on certain requests, and I already have SSL setup over the wire (so all requests occur over https). My web API will eventually be exposed as a service to other web applications.

Problem

What authentication method do people recommend for a web service that is to be consumed by mobile devices, and eventually other web applications?

These are what I see as my choices. Can you tell me when would be appropriate use cases for each one?

  1. I can do HTTP Basic authentication
  2. I can do HTTP Digest authentication
  3. I can implement OAuth authentication (1.0 or 2.0)?
  4. I can pass the credentials as parameters in my request
  5. I can use an authentication method above, and then pass a delegate/token around for authentication
  6. I can implement my own custom HTTP authentication headers
  7. I can use cookies and pass those to the server on each request
  8. Other...?

Need

If you have one leaning one way or another, I'd like to know why you would choose that method. Better yet, if you're doing this in Grails, I'm very interested.

I already know...

I've already read through the excellent answers here and Richardson and Ruby's book, Restful Web Services.

Community
  • 1
  • 1
KappaMax
  • 324
  • 2
  • 10

1 Answers1

1

REST is stateless protocol, thus using "work sessions" - I mean login/work/(auto)logout concept is somewhat questionable. Sending credentials as a parameter with each request seems to be the most often used method due to its simplicity. Just keep in mind that

1) The api url must be SSL only - it makes sense to use a dedicated domain AND ip address, e.g. api.example.com and configure your web server to handle SSL only for this address and domain. Just to avoid accidental disclosure of credentials.

2) Avoid using login/password with the request if possible, use "API key" (a shared secret) instead. You always may use "API key" instead of login/password if authentication is all you need, that is you do not need authorization (all users share the same permissions) and no need for logging (who did what).

3) Rather than sending the API key with each request, it is better to "sign" the request using shared secret and supply the signature. With the key long enough you may use this technique over plain unencrypted http.

=== responding to a comment ===

If you need authorization, just use basic authentication:

HTTPBuilder builder = new HTTPBuilder("https://api.example.com/v1/foo/bar")
builder.auth.basic(login, password)
builder.headers.put('Accept', 'application/json')
def result = builder.request(POST, JSON) { req ->
     body = [
                ....
            ]

     response.'201' = { resp, json ->
                ....
     }

     response.success = { resp, json ->
                ....
     }

     response.failure = { resp ->
                log.error "failure, ${resp.statusLine}"
     }
}
Alex Pavlov
  • 991
  • 6
  • 9
  • Thanks Alex, I'm already encrypting my connections and versioning my API, so https;//api.example.com/v1/method is pretty standard. However I am requiring authorization as well - sorry if that wasn't clear. Users do not always share the same resources. – KappaMax Dec 19 '12 at 20:59
  • Alex, that's actually my question. Okay, since my mobile app isn't storing the username and passwords, but instead just storing an API token upon successful login, would Basic Authentication be appropriate or just tagging my token along in subsequent requests? I've been down several roads, from cookies to 2-legged OAuth, and can't seem to find a best practice accepted solution. – KappaMax Dec 26 '12 at 19:48
  • How exactly your app stores the token? Does it require to enter the login/password on program restart? – Alex Pavlov Dec 29 '12 at 00:42
  • Yes, the user will have to enter username and password on application start, that's sent to the server along with some device specific info and exchanged for a token. The token is sent in subsequent requests. – KappaMax Jan 02 '13 at 15:45
  • So, your app does not store any credentials in permanent memory: user id, password, the token - all are the run time variables. I wonder, what are the benefits of using session (auth token) here? You still need SSL connection and you still have to force SSL-only communications. And answering your question: No, you can't use the token with basic authentication, you must furnish login/password with each and every request. – Alex Pavlov Jan 06 '13 at 00:51
  • I know BasicAuth is username:password in an authorization header. What I'm wondering is in practice do people use headers to send tokens in lieu of credentials, not basic authentication perse, but more of a home brewed authentication and authorization. Yes, everything is over SSL. Or would you have the app store username/password and send that with every request. Again, I'm trying to figure out from people who do this what they actually do, as opposed to what they should do. – KappaMax Jan 10 '13 at 21:31
  • 1
    Actually, I would be looking for the information about why they do this or that, which is not necessary what they actually do. Anyway, from people who really do this in real projects being published on iTunes App Store and WordPress plugins: basic auth over ssl if user identity matters (permissions or logging), API key in url otherwise. – Alex Pavlov Jan 11 '13 at 23:02