Currently in OSM when a user logs in with his credentials access token is generated and id of that token is a 32 bit randomly generated string. All the tokens generated are stored in MongoDB under tokens collection.
This feature is to Implement JWT Authentication for security and which doesn't require to store tokens data in MongoDB.
Demo or definition of done
When a user logs in, JWT should be generated and could access APIs with JWT
Designs
Child items
...
Linked items
0
Link issues together to show that they're related or that one is blocking others.
Learn more.
@adurti, if we go on that path, we should at least avoid misinforming the user who uses the NG-UI by removing the logout button (or making it unclickable when JWT tokens are being used)
@escaleira for Authorization of other APIs, the bearer token is stored in the local storage, UI will take this token and attach it to Authorization headers and hit the API.
Currently logout has two functionalities, removing tokens from local storage, which is done be NG-UI, and deleting tokens from database, which is done by NBI through API, so even though there is no need of delete tokens API in case of JWT implementation(as JWT doesn't store tokens in database), but UI needs this logout button to delete token id from local storage
Another matter I think is essential to pay attention to is that JWT is used for authorization (that is, verifying which permissions the analogous entity has), although it can also be used for authentication. Therefore, if we are to adopt JWT tokens, we can make some enhancements to the OSM authorization management:
The authentication authority can define the user's role for each project and the permissions associated with that role.
In each call made to the NBI, the NBI does not need to fetch that info from the database; it only needs to verify if the JWT token is valid and obtain its roles and permissions.
The NG-UI does not need to call the NBI to gather which roles and permissions are associated with the authenticated user; it only needs to decode the JWT token.
@adurti We have been discussing this feature in the TSC call on Tuesday Feb 20th. We think that the use of JWT tokens should be restricted to User authorization, not authentication. For authentication, the most practical way seems to keep the Bearer token authentication.
Please clarify the rationale for the use of JWT tokens for authentication. Is there a problem with saving the bearer tokens in the DB? Is there any scalability issue? Please elaborate.
@escaleira existing workflow of role permissions in NBI:
NBI verifies whether the token is valid(token expire time)
checks for the RBAC as true or false.
with the implementation of JWT, checking for the RBAC will not be disturbed. we will only modify the validation of token, and moreover role permissions is a little sensitive data, keeping that in token might not be a good practice.
@garciadeblas User authorization with JWT can be done by decoding a JWT token, we can get this JWT token only with authentication using JWT. so without authentication with JWT, authorization cannot be done.
There are no issues with using Bearer token and storing them in DB, JWT is just an alternative to bearer token that can be used for authentication.
JWT are stateless and are intended for inter-party communication. JWT have expiration time. However. If a user logs out from UI, the JWT will be still valid and a malicious user could use it.
According to NIST 800-63B, section 7.1, point 3, secrets (session tokens) "SHALL be erased or invalidated by the session subject when the subscriber logs out.". https://pages.nist.gov/800-63-3/sp800-63b.html
@escaleira@garciadeblas as JWT itself doesn't have the token revocation, we will implement it logically in NBI by blacklisting the revoked tokens:
1. Currently NBI stores token in a dictionary(tokens_cache in auth.py file) as well as in database, initially NBI checks this cache if not, then it gets token from the database.
2. Similarly we can define a list(jwt_revoke_tokens_cache) which stores the revoked JWT tokens along with expire time once user hits logout API, if user uses the token after logout then NBI will cross check with the tokens present in the list and throw an exception.
3. the expired tokens will be deleted from the list for every 30 min
For the defined NFV-MANO interfaces, where OAuth2.0 is used for API access control, NFV access token is defined
as a JSON Web Token as described in IETF RFC 7519: "JSON Web Token (JWT)" [8], including claims defined in
clause 5.5 that bind this NFV access token to the TLS client certificate of the API consumer that receives the NFV
access token from the Authorization server, and restrict the use of the NFV access token.
In this context, the JWT is recommended for authorization, not authenitcation.
@garciadeblas Authorization with JWT is possible only with JWT token.
If we implement JWT for authorization the end user (who hits the API i.e. UI) should have JWT token which should be added to authorization headers. In order to get this JWT token for the user NBI have to generate the JWT token, so authentication is also required with JWT. and moreover, the flow would be same with the current authentication. only change is, in bearer token JSON object (with user info and expire time) will be sent as the response whereas in JWT the same JSON object will be encoded as JWT and sent as the response
First, I think it is important to note the scope of the referred documents. The document @adurti referred to, the ETSI GS NFV-SEC 022 (whose most updated version can be found at https://www.etsi.org/deliver/etsi_gs/NFV-SEC/001_099/022/04.05.01_60/gs_nfv-sec022v040501p.pdf) appears as an analysis of the authentication and authorization methods that we can use on the APIs between the multiple blocks of the NFV-MANO architecture. We must remember that these APIs are for interaction between software blocks and not for end-user interaction. Consequently, there is no such thing as a logout, as there are no real users (people). This fact leads to this document not contemplating that aspect of the session handling, as it is out of the scope. Since this document describes the handling of authentication and authorization between software blocks, it describes not only the usage of JWTs (that are described as authorization tokens throughout the document and are created by an OAuth server, OAuth 2.0 being an authorization protocol) but also that they shall be used under mutual TLS. As a consequence, the JWT is even created for a specific client certificate (sections 5.4 and 5.5), and, therefore, if a third party steals that token, it can not use it with success, as it does not possess the client certificate. This aspect goes in line with one of the concerns I already reported: if we use JWTs as a session token, without any other mechanism in place, if someone steals the token, it can impersonate the user, even if the user logs out. We must remember that there is no logout between software entities, but in the mechanism described in this document, if someone steals the token, it can not impersonate the client.
Then, there is another issue with this document. It is primarily informative, and that is apparent when we analyze the requirements defined in section 4.3 and verify that not all of them are tackled in section 5. An example of such a requirement is the Acc-Token_013, which defines that "it shall be possible to revoke an access token." This requirement, once again, is the same issue I already talked about: how can a server revoke a token (for example, upon user logout?)? A possibility is to keep a log of all revoked tokens. However, this characteristic goes against what this feature was initially about: ditching saving tokens in the database.
That said, as far as I understand, this feature intends to change the session token from bearer to JWT since JWT is stateless, and therefore, we no longer need to save tokens in the database. Obviously, the authentication process (the user giving the username and password) is still required. However, for the reasons already presented in this and previous messages and the last TECH meeting, using JWT would require us to use bearer tokens as we are using now (and only using JWTs for authorization, while the bearer token is still used for session handling), or we maintain a list of revoked tokens which, as I referred previously, goes against what you are proposing (we continue to save tokens in the database, just in another context).
Having all of this in mind, we also need to remember that security mechanisms and protocols are not mere tools to use just when we need to mark a checkbox or when we need to say that we are using the most up-to-date security measures. We must have a problem, study it well, analyze why it exists, and how it can be tackled most adequately. Only then can we choose which security tools we can use that can tackle our problem. Not the other way around. Therefore, what is the security problem at hand? Why do you want to use JWTs instead of the current session tokens? As far as I can see, we do not seem to have any security risk when using bearer tokens as session tokens. And, because of everything I have pointed out, starting to use JWTs for session handling with all of these constraints would probably introduce more complexity, which increases the probability of having real security risks that we do not currently have. Once again, using them for authorization only might be a good idea (mainly because it would save the NBI from checking the database for user permissions every time there is a new API call, hence improving its performance). However, regarding session handling, I do not see the point.