does JWT containing userID need verification from the database? - node.js

I sign a JWT (JSON Web Token) with userID and iat (issues at) like so
jwt.encode({sub: user.id, iat: timestamp}, jwtSecret);
When I receive a JWT from the client, I decode it to extract the userID. Do I need to validate the userID by checking its existence in the database every time I need to allow the user to access a secure route (see first example)? Or can I just assume that the user is who she says she is, and allow her to access the secure path?
My feeling is that I need to access the database to validate the user on every request, this would be expensive and defeat the purpose of using a JWT.

Your token is signed. If someone changes the token on client side, it would fail validation and the server side framework would reject it. Therefore you can trust your token.
Of course, the jwtSecret should be a secret only known by your authentication server and resource server.
You generate the token only if you trust the user who requested it.
You trust the token as long as it has not expired and can be verified with the secret.

The whole idea of JWT is that can verify the integrity of the claims contained within it. If you can decode successfully the token you can be sure that this token contains information previously encoded by you. For someone to pass malformed data has to also know the secret you use to sign the tokens.
For more information read this.

Related

how can signing/encryption of token based authentication work for a stateless server (REST)

I have clients which are all browsers.
All clients render just a single page application getting data from a Web API.
The design of the API follows REST principles.
This is my authentication flow:
I use basic authentication over SSL for my login view.
If the user`s sent username and password are valid I put a token string into the response
This token is stored in the local storage on client side
Each further request to a ressource endpoint of the server API includes the token.
Before I do further investigation with the token like checking its expiration date:
I need to know wether the authenticity of the token is still valid or someone has modified it. This assumes that the token was signed with a key before.
OR
I need to decrypt the encrypted token.
Question 1) Do steps 6 and 7 make sense using SSL ?
Question 2) Lets assume steps 6 and 7 make sense then I would have done the following:
When the for example json web token (JWT) after successful login is created I sign it with a key. This key is somewhere on the server stored maybe in an xml file or in a singleton class.
Wherever I store this sign key when I create the token I have to use the same key to validate the token. The same is valid for the encryption of the token. How is it possible to use different sign keys for a token maybe on a user basis. That means each authenticated login gets a token with an individual sign key.
The next time the user is requesting a resource endpoint I want to know whether the token has still the authenticity. But I can check this only with the same sign key the token was created with.
Question 3) Where should this sign key be stored ?
If you use JWT you have different possibilities of security:
Sign the token (see JWS). In this case a man-in-the-middle can still read the contents of this token but cannot modify it because he doesn't have the key to sign it and when the server checks the authenticity of the token it will detect that it has been tampered with
Encrypt the token (see JWE). In this case a man-in-the middle cannot read the contents of the token, nor he can modify its contents.
Using SSL in your case would ensure that the token cannot be stolen by man-in-the-middles. So unless you have some super secret information stored inside this token, signing it should be sufficient. Obviously the signing key should be stored on the server only and not shared with the rest of the world.
As far as your question about signing the token with different keys depending on the user is concerned, I don't think this is necessary.
Personally I would use a JWT token which contains only a minimum information like the exp and jti claims and sign it with a secret key. Then I would use the value of this token as key in a key/value store on the server (could be some cache implementation like memcached or NoSQL DB) and would associate the username and any other necessary information to this token. The value will be cached for the duration of validity of the token. When the client sends the JWT token to the server, the server would validate the signature of the token to ensure that its value hasn't been tampered with and then look it the cache for the associated user information.
SSL prevents tampering by men in the middle but what about the end users themselves? I don't trust anybody including end users. Any evil end user can hijack the token from a common machine or some one else's and simply send the token back to the server. If that is okay to you in terms of the security requirements you have, SSL is good enough.
However, people use the term token to indicate any kind of blob. But a software security token is supposed to be the container of claims. If you do indeed use your token to store claims, it is very important to check the integrity by validating the signature. Even a legit user can add bogus claims and push the token over to the server through HTTPS.
You can have a key per user. You can store it where ever you want it. But you need to ensure the security of the keys.

NodeJs JWT token storing

I'm working on creating the user authenticate service and using the passport-jwt-strategy for authentication. but stuck on the point for storing the generated 'JWT token' into the user schema. Is it necessary to store the JWt token into the user model?
JWT are created to be stored on the client side.
The only thing the server should need is a secret key with which to verify the token signature, to make sure it has not been tampered with.
If you need to be able to invalidate session, then maybe another form of validation should be used.
It is not necessary to store jwt token, from server side you just need to verify jwt token, verify auth and roles of jwt token, jwt token should store in client side only. Jwt provides session less authorization to user. For more visit jwt official site.
JWT is stateless and does not need to be stored on the server side. However, the spec denotes a property jti which is the ID of the token. This one might be worth storing to, say, blacklist the one specific token later.

JWT Token strategy for frontend and backend

I'm writing an application with a front end in emberjs and backend/server-side in a nodejs server. I have emberjs configured so that a user can login/signup with an 3rd party Oauth (google, twitter, Facebook). I have a backend written in express nodejs server that hosts the RESTful APIs.
I do not have DB connected to emberjs and I don't think I should anyways since it's strictly client side code. I'm planning on using JWT for communicating between client side and server side. When a user logins with their oauth cred, I get a JSON object back from the provider with uid, name, login, access_token and other details.
I'm struggling with picking a strategy on how to handle user signup. There is no signup process since it's OAuth. So the flow is if the user is not in my db, create it. I do not support email/password authentication. What would be the flow when a user signs in with an OAuth provider for the first time? Should emberjs send all the details to the backend on every sign in so that backend can add new users to the db?
What should be part of my JWT body? I was thinking uid and provider supplied access token. One issue I can think of here is that provider specific access token can change. User can revoke the token from provider's site and signs up again with emberjs.
I'm open to writing the front-end in any other javascript client side framework if it makes it easier.
If we're talking about not only working but also secure stateless authentication you will need to consider proper strategy with both access and refresh tokens.
Access token is a token which provides an access to a protected resource.
Expiration here might be installed approximately in ~1 hour (depends on your considerations).
Refresh token is a special token which should be used to generate additional access token in case it was expired or user session has been updated. Obviously you need to make it long lived (in comparison with access token) and secure as much as possible.
Expiration here might be installed approximately in ~10 days or even more (also depends on your considerations).
FYI: Since refresh tokens are long lived, to make them really secure you might want to store them in your database (refresh token requests are performed rarely). In this way, let's say, even if your refresh token was hacked somehow and someone regenerated access/refresh tokens, of course you will loose permissions, but then you still can login to the system, since you know login/pass (in case you will use them later) or just by signing in via any social network.
Where to store these tokens?
There are basically 2 common places:
HTML5 Web Storage (localStorage/sessionStorage)
Good to go, but in the same time risky enough. Storage is accessible via javascript code on the same domain. That means in case you've got XSS, your tokens might be hacked. So by choosing this method you must take care and encode/escape all untrusted data. And even if you did it, I'm pretty sure you use some bunch of 3rd-party client-side modules and there is no guarantee any of them has some malicious code.
Also Web Storage does not enforce any secure standards during transfer. So you need to be sure JWT is sent over HTTPS and never HTTP.
Cookies
With specific HttpOnly option cookies are not accessible via javascript and are immune to XSS. You can also set the Secure cookie flag to guarantee the cookie is only sent over HTTPS.
However, cookies are vulnerable to a different type of attack: cross-site request forgery (CSRF).
In this case CSRF could be prevented by using some kind of synchronized token patterns. There is good implementation in AngularJS, in Security Considerations section.
An article you might want to follow.
To illustrate how it works in general:
Few words about JWT itself:
To make it clear there is really cool JWT Debugger from Auth0 guys.
There are 2 (sometimes 3) common claims types: public, private (and reserved).
An example of JWT body (payload, can be whatever you want):
{
name: "Dave Doe",
isAdmin: true,
providerToken: '...' // should be verified then separately
}
More information about JWT structure you will find here.
For any OAuth workflow you should definitely use the passportjs library. You should also read the full documentation. It is easy to understand but I made the mistake of not reading the the whole thing the first time and struggled. It contains OAuth Authentication with over 300 Providers and Issuing Tokens.
Nevertheless, if you want to do it manually or want a basic understanding, here is the flow that I'd use:
Frontend has a login page listing Sign-in with Google/Facebook etc where OAuth is implemented.
Successful OAuth results in a uid, login, access_token etc. (JSON object)
You POST the JSON object to your /login/ route in your Node.js application. (Yes, you send the whole response regardless if it's a new or existing user. Sending extra data here is better than doing two requests)
The backend application reads the uid and the access_token. Ensure that the access_token is valid by following (https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#checktoken) or asking for user data from the provider using the access token. (This will fail for invalid access token since OAuth access tokens are generated on a per app/developer basis) Now, search your backend DB.
If the uid exists in the database, you update the user's access_token and expiresIn in the DB. (The access_token allows you to get more information from Facebook for that particular user and it provides access for a few hours usually.)
Else, you create a new user with uid, login etc info.
After updating the access_token or creating a new user, you send JWT token containing the uid. (Encode the jwt with a secret, this would ensure that it was sent by you and have not been tampered with. Checkout https://github.com/auth0/express-jwt)
On the frontend after the user has received the jwt from /login, save it to sessionStorage by sessionStorage.setItem('jwt', token);
On the frontend, also add the following:
if ($window.sessionStorage.token) {
xhr.setRequestHeader("Authorization", $window.sessionStorage.token);
}
This would ensure that if there is a jwt token, it is sent with every request.
On your Node.js app.js file, add
app.use(jwt({ secret: 'shhhhhhared-secret'}).unless({path: ['/login']}));
This would validate that jwt for anything in your path, ensuring that the user is logged-in, otherwise not allow access and redirect to the login page. The exception case here is /login since that's where you give both your new or unauthenticated users a JWT.
You can find more information on the Github URL on how to get the token and to find out which user's request you are currently serving.
To answer the two specific questions that you posed:
What would be the flow when a user signs in with an OAuth provider for
the first time? Should emberjs send all the details to the backend on
every sign in so that backend can add new users to the db?
Whenever a user either signs up or logs in via oauth and your client receives a new access token back, I would upsert (update or insert) it into your users table (or collection) along with any new or updated information that you retrieved about the user from the oauth provider API. I suggest storing it directly on each users record to ensure the access token and associated profile information changes atomically. In general, I'd usually compose this into some sort of middleware that automatically performs these steps when a new token is present.
What should be part of my JWT body? I was thinking uid and provider
supplied access token. One issue I can think of here is that provider
specific access token can change. User can revoke the token from
provider's site and signs up again with emberjs.
The JWT body generally consists of the users claims. I personally see little benefit to storing the provider access token in the body of a JWT token since it would have few benefits to your client app (unless you are doing a lot of direct API calls from your client to their API, I prefer to do those calls server-side and send my app client back a normalized set of claims that adhere to my own interface). By writing your own claims interface, you will not have to work around the various differences present from multiple providers from your client app. An example of this would be coalescing Twitter and Facebook specific fields that are named differently in their APIs to common fields that you store on your user profile table, then embedding your local profile fields as claims in your JWT body to be interpreted by your client app. There is an added benefit to this that you will not be persisting any data that could leak in the future in an unencrypted JWT token.
Whether or not you are storing the oauth provider supplied access token within the JWT token body, you will need to grant a new JWT token every time the profile data changes (you can put in a mechanism to bypass issuing new JWT tokens if no profile updates occurred and the previous token is still good).
In addition to whatever profile fields you store as claims in the JWT token body, I would always define the standard JWT token body fields of:
{
iss: "https://YOUR_NAMESPACE",
sub: "{connection}|{user_id}",
aud: "YOUR_CLIENT_ID",
exp: 1372674336,
iat: 1372638336
}

Understanding authentication flow with refresh and access tokens on nodejs app

I know there are already many posts about Oauth, Oauth2, JWT, etc.. I have read many and I more confused than ever so I am looking for some clarification. I will propose my view on the subject and I hope somebody can tell me if my implementation is secure enough or what I am doing wrong and how to improve it.
I am building an API Rest server for serving my resources to my users. Let's suppose it is a bank app where users can deposit, withdraw and transfer money.
I am using nodejs, hapijs, jsonwebtokens, and bcrypt for my server. I want to implement two token authentication flow (Oauth2).
This is the way I am doing it:
User logs in to the auth server by giving some credentials (username and password).
The server verifies the user's credentials, if they are valid, it will grant access to the user and return a refresh token and an access token.
These tokens are saved into the local storage of the browser or mobile device.
The access token:
is signed as a jsonwebtoken.
contains issued date, expiration date (5 min), user data (id, username).
The refresh token:
is signed as a jsonwebtoken and encrypted with bcrypt.
contains a unique identifier
may contain an expiration date
is saved in the database.
As long as the access token is valid, that means, it has not expired and contains valid user data, the resource server serves the user the requested resources.
When the access token is no longer valid, the auth server requests the client to provide a refresh token in order to issue a new access token
The server receives the refresh token from the user, decrypts it, compares it to the one in the database, checks if it has been revoked, and checks its unique identifier.
If the refresh token passes all tests, the server issues a new access token to the client.
If the refresh token fails one test, the server requests the user to re-authenticate.
Notes: I am trying to avoid the usage of cookies.
Questions:
If the user is able to steal an access token, I guess it can also steal the refresh token. So, how can I make the refresh token more secure?
Is my perspective of the Oauth2 flow correct?
What can I improve?
Am I missing something?
The reason OAuth2 is so confusion to many people is because it uses different authentication flows depending on what kind of client is used.
OAuth2 distinguishes two client type, confidential or public. Next to that, there are 2 grant flows that are redirection based (auth code and implicit) which are meant to be used with a browser or browser control.
The other two flows (resource owner password and client credentials) are meant to be used from non-browser apps (CLI, background services, trusted mobile clients).
I've described the different flows and when to use them in more detail in this answer here.

How to prevent a DataContract's content from being modified by the client with WCF?

I am building an application which requires the user to login at start-up.
The authentication process is as follows:
User inputs username / password.
client sends username + password to Web Service.
Web Service authenticates the user with hashed password from the DB.
Web Service returns a token to the client which contains one of those three values:
1) Username is invalid.
2) Password is invalid.
3) User is authenticated.
The token is used by the client to determine the next course of action.
The token is passed to the service with every subsequent calls made by the client. The service rejects the call if the user is not authenticated.
The token is encapsulated within a DTO, which is a DataContract. The token itself is a DataMember. DataMembers require that the property have a setter and a getter. This means that clients are now able to set a value for the token, which is bad. Clients could now technically flag themselves as authenticated.
How would I go about preventing clients from modifying the value of the token ? Are there any patterns that could help me here ?
The server must 'know' the token and validate it.
There's no way that you can restrict the client from changing the token. Think about it - I send you a DTO, basically a bundle of information. Later on, you send that bundle back to me. How could I possible stop you from changing what's in the bundle? The only thing I can do is check that the bundle is valid, you haven't changed anything that I don't expect you to change, and so on.
If your token is a simple authenticated flag then that's a bit of a disaster. Imagine a website that accepted a logged in parameter that just trusted me. You tell the webserver that you're logged in and it believes you? www.visa.com/account.html?account=123456&loggedIn=true doesn't seem very secure.
In platform agnostic world you can use encryption to create a secure token that can be validated. You already have a token, so perhaps you could add some encrypted content to the token that validates a user. The client doesn't know what the data is, and can't decrypt it easily. They need to return the token to the server on each request. The server can decrypt the token which confirms that the user is authenticated.
Of course the tokens need to expire, and need to be secure and un-guessable. In a Windows world it might be simpler to use Windows authentication, or one of the rolled-in .NET authentication patterns.

Resources