-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validate and keep track of all users JWT token #23
Comments
discussion starts from commit 931134c |
We must make some decisions on how to use JWT and how to validate them. Here I will write some notes to take these decisions all together. First of all, citing http://security.stackexchange.com/a/99741, we must remember how JWT are usually used:
Reading around i see that validation based on action is the first reason people give up on the stateless JWT system. I didn't know, and personally I don't like it too much. So here is my summary, after documenting my mind, of the different characteristics that could be implemented:
|
Also, to remember for the future security, still citing from the source:
And, in fact, we have sequential at the moment. |
@mdantonio we should do something here and close it in the very beginning of the next week |
So we should replace IDs with UUIDs We can create UUIDs from graph-side by installing with library: https://github.com/graphaware/neo4j-uuid Otherwise we can create such IDs from python-side:
Note that to force the invalidation of tokens an option is to change the user ID. I don't like very much to change the user ID but we could merge the two things:
|
I like that. So we are going to have Sounds great! |
You may start from this model |
It is done. We have to decide which information add to the token (creation date, TTL, IP address?)
We need to modify the verify_token method to check if the uuid contained in the token (to be added) match a node in graph (uuid to be added in the model)
After implemented the UUID the invalidation will only require a refresh of the UUID in the user node
To implement this we could:
|
IP, date of expiration, last access, host(?) For standard information, see this instead: |
UUID we must check how we could do it with python to avoid the graph extension |
I like this option |
What is missing:
I found a problem: since |
You broke the tests :P https://travis-ci.org/EUDAT-B2STAGE/http-api/builds/135987324 |
OOps i broke them! |
LOL |
We may create and endpoint for admin to clean the token left hanging after launching automatic tests. |
Implemented endpoints: GET /auth/tokens |
We have to found a compromise between security (short life tokens) and ease of use (long life tokens) The auto-refresh could be a solution. So an unused token will expire in 1 week (good for security) Expiration extensions cannot be implemented if TTL is encoded in payload (change the information will change the token) but we can implement a double TTL system: In the paypload is encoded a long term TTL (1 year?) Only the database TTL can be extended and the payload long term TTL is used as hard limit to avoid immortal tokens To implement this we can use the "last_access" and "expiration" fields already added to the Token model (and still unused) + the TTL information in the payload (still to be added) |
Should we take in consideration now the oauth2 refreshable tokens? |
The Oauth2 refresh tokens mechanism has a similar purpose (extend the life of short-term access tokens) but it works with to the exchange of client_id and client_secret, required to obtain a new access token from a refresh token. We could implement refresh code exchangeable with new access tokens with the requirement of no other information... So a explicit token refresh instead on a automatic/implicit refresh as I proposed This could be a little more secure because if my access token is compromised the problem is time-limited due the short token duration. My question is why to complicate both the backend and the client implementation to gain very few in security? |
I agree, too much work for now. Let's go with the first proposal then, 2 TTL inside payload + database. |
Code refactoring to implement the token payload with TTL |
Note that jwt.decode checks by it self the token validity by verifying both nbf (not before) and exp (expiration) fields |
Filtering token nodes based on jti instead of token string updated the last_access date see pdonorio/restangulask#23
The double TTL workflow is now working (for both graphdb and relational). You can make some test, then the issue can be closed. I not really sure about the choice to disconnect invalid tokens instead of delete it... We create a lot of garbage in the graph... maybe in the future you may re-consider this choice. A point is missing:
I open a dedicated issue for this sub-sub-task |
Could we already prepare the method that cleans those disconnect tokens with a Cypher query? |
Cleaned code for graphdb see pdonorio/restangulask#23
Implemented the endpoints
Since the role decorator is still missing i used an endpoint name with an explicit intention (admin only), to be modified after the implementation of role restrictions. To not forget it i added a logger.critical("This endpoint should be restricted to admin only!") when using this endpoint relational endpoint is not tested (if you test it you can close the issue) |
Verified! |
Finally we decided to modify the invalidate token to delete the node instead of only disconnect it from the user I'm implementing this modification in graphdb auth, the same approach should be replicated on sql and mongo |
Todo list here:
|
Done here: |
Mainly we have different subtasks:
The text was updated successfully, but these errors were encountered: