Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RESTful user authentication service

Hey folks, this seems to have been discussion fairly often but I want to make a simple, watered down question around doing authentication with RESTful services. The scenario is as follows:

  • There is a system that houses registered users for an application. The system exposes a RESTful API for accessing these users.
  • There is a front-end application that has a login form. The application can either be internal, or external.
  • The front-end application needs to use the data in the User system to authenticate a user.

The question now is how to authenticate a user whose credentials (username/password) are entered in the client application against the data in the User system such that it is secure and performant? For the sake of this question, suppose the client application is internal to some sort of Intranet but the applications will not reside on the same machine and may only communicate through the service.

I understand the idea of having the application being "hypermedia driven" but we should be able to provide filtering/searching services. For example, consider the resources and API as below:

  • http://example.com/users
    • GET - retrieves all users (paged, hypermedia driven)
    • POST - creates new user
    • PUT/DELETE not supported
  • http://example.com/users/[id]
    • GET - returns a full representation of a user with id = {id}
    • PUT - updates user, takes in any predefined media type
    • DELETE - deletes the user (with appropriate authorization)
    • POST not supported

Based on the above, my idea would be have the client application GET on the user listing, filtering by username. The service will return the hashed password and salt to the client, the client will perform the authentication.

Thoughts?

like image 621
djunforgetable Avatar asked Jan 07 '10 05:01

djunforgetable


People also ask

How do I authenticate a user in rest?

The way to do authentication or authorization in the RESTful service is by using the HTTP Authorization header as defined in the RFC 2616 HTTP specifications. Every single request should contain the HTTP Authorization header, and the request should be sent over an HTTPs (SSL) connection.

How do I authenticate a user in REST web services?

Use of basic authentication is specified as follows: The string "Basic " is added to the Authorization header of the request. The username and password are combined into a string with the format "username:password", which is then base64 encoded and added to the Authorization header of the request.

What type of authentication is used in REST API?

One of the most common authentication methods used by REST APIs is username and password authentication. There are several different types that use a username and password but the most common one is HTTP Basic authentication.


2 Answers

If I understand your question correctly, you are looking to implement a generic service that will handle authentication, so that you can re-use it for different applications.

I suggest you take a look at OAuth which has been built for precisely this problem domain.

like image 71
Stefan Tilkov Avatar answered Oct 17 '22 09:10

Stefan Tilkov


Passing the username and the salt back is unnecessary and a real security risk.

Perhaps you could consider this approach:

Have the client pass the username and password to the server via Basic Authentication

The server fetches the encrypted password for the username along wiht the salt

The server encrypts the given password using some encryption method, using the salt to assist the algorithm (Ruby code follows):

def User.authenticate(login, password)
    ok = false

    user = User.find_by_login(login)

    if user
        #
        #   user contains the salt, it isn't passed from the client
        #  
        expected_password = hash_password(password, user.salt)

        ok = (user.password == expected_password)
    end

    return ok
end

There are multiple places to use this kind of approach but I like to do it in Rack.

Last point, do it all on a HTTPS connection

like image 42
Chris McCauley Avatar answered Oct 17 '22 08:10

Chris McCauley