I am currently creating a website which users can view and modify their widgets. All interation with the widget data stored on my server will be done through RESTful web services. For example, if a user wants to see a list of their widgets the flow of execution would be something like:
https://www.example.com/Login.htm
and authenticates with the server (in my case through an OpenID provider)https://www.example.com/Widgets.htm
getWidgets()
will be called. getWidgets()
will call my web service https://www.example.com/Services/Widget/12345
renderWidgets(widgets)
will update the html pageI don't want anyone else but user 12345 accessing their own widgets so I guess getWidgets()
will have to provide some authentication to my web service. I'm not sure what the best way would be to achieve this.
I was thinking that the client and server could have a shared secret that getWidgets()
will send to the web service. The server could generate this secret as random string (number, GUID or whatever) and include it in the response header when the client requests the initial HTML page. The client would use this secret key when sending requests to the server.
Does this sound like a sensible idea?
This is a common requirement so is there a standard way of achieving the same thing? As far as I am aware this is outside of the scope of OpenID and OAuth would not be suitable.
Thanks in advance.
Basic authentication is an HTTP-based authentication approach and is the simplest way to secure REST APIs. It uses a Base64 format to encode usernames and passwords, both of which are stored in the HTTP header.
Username & Password Authentication 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.
The Web Services Security message receiver authenticates the sender by validating the user name and password against the configured user registry. With the LTPA method, the sender attaches the LTPA BinarySecurityToken it previously received in the SOAP message header.
Rest assured has four types of authentication schemes. They are basic, digest, form, and OAuth authentication. By default, rest assured uses a challenge-response mechanism. But, a preemptive directive sends the credentials without waiting for the server.
This is a great question - but I think your solution may need to be a bit more complex than you are thinking.
In general, the way in which you want to authenticate this kind of scenario is in a 2-stage handshake. The first step is for your application to provide the server a private key (generated by the server, unique to the client application) to authenticate that it is, in fact, a valid client. This is what provides authoritative evidence to your server that the request is coming from software it knows and can trust.
The second step, then, is that when a user goes to log in to your client application, they provide a username / password combination. This information, along with your application key, should all be sent up to the server via SSL.
SSL encrypts the data so that a third-party with a packet-sniffer can't read the data in-transit, and the server does the following:
401: Unauthorized
response, or other similar error.At this point, the client can utilize the returned session ID without having to continue to re-submit the application key.
Your Application
Now, in your case, you may be actually hosting the client/server in the same application and on the same server. In this case - you can generally skip all of the pieces revolving around the private application key - and simply disallow cross-site script requests instead.
Why? - because the thing you're really protecting against is the following:
Server A hosts your RESTful API. Client's B, C and D host clients which will rely upon Server A's API. What you don't want is for Client E (not your application - and malicious) to be able to access Server A either by bypassing or stealing the credentials of one of the other Clients.
If, however, both client and server are hosted in the same place, and therefore have the same URL - i.e. the RESTful API resides at www.yourdomain.com/api
and the client resides at www.yourdomain.com/
- you can generally just not allow any AJAX type requests which originate outside of yourdomain.com
- and that is your layer of security.
In this case, the following is all you should need to do to have a reasonable level of security:
/auth/login
(or whatever your login POST
method is) to come via SSL (in C# this can be done by using the [RequireHttps]
attribute on the method or controller).What should your cookie contain?
Ideally, the cookie should contain 2-way encrypted data that ONLY your server can decrypt. In other words - you might put something like the user's username
or user_id
inside the cookie - but 2-way encrypt it using Rijndael or another cryptography system - using an encryption password that only your server has access to (I suggest a random string of characters).
Then - when you receive subsequent requests with the cookie attached, you can simply do the following:
401: Unauthorized
response (this is an altered or fake cookie)I hope this helps. :) If not - feel free to post any comments and ask questions, and I'll try to clarify.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With