RESTful authentication scheme - rest

I need to implement an authentication scheme for a RESTful architecture. From several articles which I have read include basic Authentication using HTTPs and Session management using Cookie.
However I'm not well understanding the use of cookie. What i understands is that user first sends credentials. The server checks if the credentials are Ok. If yes, the server generates an authorization token and place it in the cookie. Onwards, on each and every request, server checks the validity of the token in the cookie.
But how does the server know that the content of the cookie is valid. Does it stores it somewhere and then it compares it??

The key point here is the authorization token. When generating one and sending back to the client, you store the auth token along with the username in let's say a database. You store the auth token in the cookie. The client on subsequent requests sends you the username and the cookie alongwith which contains the auth token. You verify this token against the supplied username and then perform the action per need.
However, do note that settings cookies makes your webservice call stateful and defeats the purpose of REST.
To achieve authentication/authorization, instead of setting the authorization token in the cookie, send it back as a response value. The client reads the value of auth token and then supplies the same in every REST request as a parameter of request body. Thus, you won't need to set cookies. This you may term as the toned down and simpler version of what is implemented in OAuth based API access.

I'm not an expert, but a good starting point to understand this is the section on Sessions in Hartl's book.
If I'm not mistaken it works as follows:
When the token is created, it uses a formula, e.g. the username and a unique user key (a salt) encrypted together. Both the username and the salt are stored in the database, and the salt is unique to that user. So, as you would do to compare if passwords match, to check the validity of the cookie you recreate the token and compare it to the one in the cookie. If it matches, then the right user is logged in and therefore authorised.
Hope this helps, or at least points you in the right direction :)

Related

Mobile app + REST API authentication

I want to build a REST API which will be used by both mobile app and also a website. I was wondering how would I go about implementing a simple login system for users?
For a simple website, after checking the username and password, one could set a SESSION variable and have the user "logged in".
Now, REST is stateless so I suspect that the above is not the way to go about. I thought that a possible solution would be to have the server generate and return an access token each time the user logs in, and the client will need to attach this access token to every subsequent request to access protected endpoints.
Is the above a viable solution or what is the industry standard for something like this?
(I found OAuth 2.0 to be overkill, but I could be wrong)
There are several token authentication schemes, but if you're looking for the industry standard, then JWT (JSON Web Token) is the way to go. Here's how the process usually goes:
Client sends his credentials (e.g. username and password) to the server.
The server verifies that the credentials are correct, generates a JWT and returns it to the client. Client saves the token in e.g. localStorage.
For each subsequent request, the client will attach the JWT as a part of the request (usually in the "Authorization" header).
Server will be able to decode the JWT and decide if the client should have access to the requested resource.
Now, some interesting features of JWT come from the fact that there is data encoded in it. Some of it everyone can decode, and some only the server can decode.
So, for example, you could encode the user's id and profile picture in the JWT so that the client can use the data from it, not having to do another request to the server to get his profile.
JWT has embedded info about expiration. The server can set the expiration time.
Another cool thing about JWTs is that they are invalid if changed. Imagine you stole someone's token, but it's expired. You try to change the expire information inside the token to some time in the future, and send it to the server. Server will deem that token invalid, because the contents doesn't match the signature attached, and a valid signature can only be generated by the server.

How RESTful token authentication works

I understand that i have to provide a token to a client upon a successful authentication. What i still don't understand is how a server validates the token and its expiration time.
If RESTful services are stateless, how is it possible to authenticate a token on the server? Could anyone provide examples of token validation?
If RESTful services are stateless, how is it possible to authenticate a token on the server?
The server stores no state, the state used to validate a token is contained inside the token e.g. an expiration date & an account ID. A very simple, pseudo, example:
if token.expiry < now then
return tokenExpired
If !findUser(token.accountId) then
return accountNotFound
return tokenOk
The server may keep track of what tokens it has issued as a security measure to ensure old tokens can't be reused, and such that tokens can't be forged. So if we take the previous example it could updated to include an additional check
if !tokenActive(token) then
return tokenInvalid
the token contains some usefull information, like the date, some values like the username or email and others fields.
If I take for example the JWT token, you will find 3 'fields of information'
1/ header
2/ payload
3/ verify signature
You will find more datas on this website : https://jwt.io/introduction/

JWT authentication & refresh token implementation

I am developing a REST application with its own authentication and authorization mechanism. I want to use JSON Web Tokens for authentication. Is the following a valid and safe implementation?
A REST API will be developed to accept username and password and do the authentication. The HTTP method to be used is POST so that there is no caching. Also, there will be SSL for security at the time of transit
At the time of authentication, two JWTs will be created - access token and refresh token. Refresh token will have longer validity. Both the tokens will be written in cookies, so that they are sent in every subsequent requests
On every REST API call, the tokens will be retrieved from the HTTP header. If the access token is not expired, check the privileges of the user and allow access accordingly. If the access token is expired but the refresh token is valid, recreate new access token and refresh token with new expiry dates (do all necessary checks to ensure that the user rights to authenticate are not revoked) and sent back through Cookies
Provide a logout REST API that will reset the cookie and hence subsequent API calls will be rejected until login is done.
My understanding of refresh token here is:
Due to the presence of refresh token, we can keep shorter validity period for access token and check frequently (at the expiry of access token) that the user is still authorized to login.
Please correct me if I am wrong.
A REST API will be developed to accept username and password and do
the authentication. The HTTP method to be used is POST so that there
is no caching. Also, there will be SSL for security at the time of
transit
This is the way most do it, so you're good here.
At the time of authentication, two JWTs will be created - access token
and refresh token. Refresh token will have longer validity. Both the
tokens will be written in cookies so that they are sent in every
subsequent requests
Storing the tokens in cookies I not dangerous in itself, but if you somehow get you JWT module on your server to read them from there you vulnerable to CSRF attacks where any webpage can trigger a users browser to send a form + you sites cookie to your server unless you use CSRF tokens. So generally they are stored in localStorage and "manually" added to request headers every time.
On every REST API call, the tokens will be retrieved from the HTTP
header. If the access token is not expired, check the privileges of
the user and allow access accordingly. If the access token is expired
but the refresh token is valid, recreate new access token and refresh
token with new expiry dates (do all necessary checks to ensure that
the user rights to authenticate are not revoked) and sent back through
Cookies
Apart from the cookie dangers, it seems safe.
Provide a logout REST API that will reset the cookie and hence
subsequent API calls will be rejected until login is done.
You don't even need to make an API call, you can simply just purge the cookies or the localStorage object and make sure your client doesn't break on missing tokens.
The standard for the express-jwt module expects the tokens to be in its own "Authorization: Bearer [Token]" header, which I would strongly recommend over cookies. The localStorage API is available all the way back to IE8 so you should be good.
Edit:
First, it's important to know the difference between XSS and CSRF attacks since they're often believed to be the same thing.
XSS is when users get unsafe JS running on your domain in other users browsers when that happens neither JWT in localStorage or sessions and JWT in cookies are safe. With httpOnly flag on cookies, you can't directly access them, but the browser will still send them with AJAX requests to your server. If this happens you generally out of luck. To prevent this, make sure to escape all user input if it's sent to the browser.
If you load 3rd party JS with script tags or iframes this might compromise localStorage unless you are careful, but I haven't worked enough with this to help you here.
CSRF is only when other domains are trying to send normal HTML forms to your server by getting the browser to send cookies automatically. Frameworks prevent this by inserting unique random strings as hidden fields and checking them again when it's submitted. JWT's in localStorage is safe from this since each domain gets its own separate localStorage area.
But ultimately all this depends on if your service will be using one single domain, in which case httpOnly cookies will be plenty secure and easier to set up, but if you wanna spread your service out on multiple domains like api.domain.com + app.domain.com or add a native app you're forced to store you're JWTs in localStorage or some other native storage area.
Hope this helps!
I asked this question two years back and also accepted the answer. However, based on my experience and study in the last two years, I'd like to answer this just in case someone stumbles on this thread with the same question.
The approach mentioned in the question is similar to the "Resource Owner Password Credentials" grant type of OAuth 2.0. However, I think it is better to use the "Authorization Code Grant" type instead and Cookie to store the tokens instead of browser localStorage or sessionStorage. I have detailed my reasons, implementation points, security considerations and references in this StackOverlow answer.
Like OP I been using resource owner password grant.
I learned so much from Saptarshi Basu's other answer in a different post I think anyone looking into OAuth Code Flow should take a look at it, it has outlined a very solid approach to auth SPA and resource servers. It primarily relies on your backend(resource server) to handle authentication with the auth provider as a private client.
However, I will just add that people looking at implementing authentication with SPA should also consider OAuth Code Flow with PKCE. The main goal of PKCE is to allow public client such as SPA to authenticate directly with auth provider. All PKCE adds, is that when a SPA app initiates authentication, a hashed value is sent to the auth provider when the user is authenticated. And after user authenticate with the authorization provider, it redirects the user back to SPA with that hashed value as well as authorization code. Now, for the next part where the SPA calls auth provider to exchange code for tokens, instead of providing client secret, it has to provide the key that was originally used to create the hashed value. This mechanism guarantees the code cannot be used by someone who intercepted the code, and the SPA doesnt need to store a client secret like a server-side app does.
Now the only thing I'm not certain at this point is which is technically more secure, server-side authentication using standard Code Flow without PKCE or SPA authenticating directly using PKCE? Most resources I could find online currently describes and recommends the latter . However I feel that letting a private server side client handle authentication (as Saptarshi Basu described) might still be more secure. I would love to hear his opinion on this as well.
My understanding of refresh token here is:
Due to the presence of refresh token, we can keep shorter validity period for access token and check frequently (at the expiry of access token) that the user is still authorized to login.
Please correct me if I am wrong.
Assuming you're talking about using JWT as Bearer-token in OAuth (and I would strongly advice to follow the OAuth 2.0 protocol), that's right.
With an additional auth-time (timestamp of authentication) claim in your JWT, you could even drop the second token and sent your access- as a refresh-token (the auth-server could then issue a new access-token if token is valid & auth-time within allowed range)... but sure, it's also good to follow the standard ;)
Anyway, there are certain additional aspects (that tend to get difficult or are even against the fundamental ideas of JWT) you should consider before using JWTs as refresh-token, as this basically means you introduce long-living JWT:
do you need to have something like forced user logout/ token revocation by subject (e.g. if user got identified as fraudulent)?
do you need to have something like revocation of a specific token (e.g. if a user looses a device)?
...
Dependent on your use-case you should consider all the possible implications, long-living tokens have as they usually require you to introduce some kind of state on your server-side (e.g. to allow revocation/ blacklisting). Keep in mind the beauty and security of the JWT concept lies within JWTs being short-lived.

Stateless Token Auth security

I'm new to ReST and am implementing a ReSTful token authentication, trying to use Django-Rest-Framework JWT, in a mobile web app in the standard way
client sends credentials
server verifies and sends token and expiration date back. Deletes token from db
client calls refresh token when user makes request and token is about to expire
on client request, server verifies token signature
on expired token mobile app logs user out. Mobile app checks expiration not server
I decided to make the mobile app check the expiration date since I read that is ReSTFul, and the server checking it requires it to store tokens which is not ReSTful
I have a few security questions regarding the above implementation:
1) Doesn't obtaining one token give the attacker complete access to the user's login no matter how many token refreshes happen?
Even if it's over https, let's say by some means a token was retrieved by an attacker, i.e. ssl interceptor proxy.Obviously the mobile application won't allow them to login, but they can grab data by calling the api with the token through any HTTP client.
2) What is the purpose of having refreshing tokens in the first place if the server considers all of them as valid?
There seems to be no forward security in this.However, if the server stored the tokens and kept their expiration dates, a complete user compromise would be stopped, but not a per session compromise. Obviously with an SSL interceptor they could still compromise the user, but would need to catch every login. However that implementation is not ReSTful.
First of all, expired tokens are valid tokens, but you can check if token expired or not, before taken any action, and reject the ones expired. There are several things you can do to increase the security of your app:
You can add the hashed password inside token. Therefore if user lost his/her mobile, when password changed in another device, you can reject the tokens with old password hash.
This one is not totally restful, but not that bad as well: you can add a table called revokedTokens in db which keeps track of id of tokens (obviously you should add it to token) user revoked, if you receive request with that token later on, you can reject it until it expires. when it expires you can remove from the table, as expired tokens won't be a problem anyway.
You can add the device's host name when user logs in to the token, and compare it with the request's host name, to have additional layer of security for ssl interceptor attack. Yes, it's not total protection, but still a bit better, as attacker needs to change his/her host name in addition to sending the token from another device.
Hope this helps.

JWT for SSO (as used by ZenDesk)

My experience with token-based authentication systems has always involved a token-exchange system. The application in which we want to authenticate the user receives a token (via request), and then securely transmits this token to the authenticating system's token exchange service, which validates the token and returns user information to the application.
I've recently come across ZenDesk's implementation of SSO, which uses JWT but no token exchange/validation step.
https://support.zendesk.com/hc/en-us/articles/203663816-Setting-up-single-sign-on-with-JWT-JSON-Web-Token-
Example PHP implementation here: https://github.com/zendesk/zendesk_jwt_sso_examples/blob/master/php_jwt.php
Basically, encoded user information is passed through a URL along with an HMAC to sign the request. The ZenDesk end will decode, validate the HMAC is valid (using a shared key), and immediately authenticate the user based on the request's user information. There is no callback to the system that generated the token to ensure it is valid.
My question is: If someone were to capture the request, and they decoded it to obtain the user information and the HMAC, couldn't they just send this up to a server farm to start iterating over secret keys until they figure out what it is (ie: making the HMACs match)? And then once you have the key, you could authenticate to ZenDesk as the CEO and make ridiculous requests?
Hopefully I'm missing something, as this approach to SSO is the simplest I've ever seen.
You are exactly right. The thing that you are missing is that - assuming the keyed hash used for the HMAC is secure and that the key is strongly random and long enough - it will be infeasible to brute force the key.