On most of the JWT (JSON Web Token) tutorial (e.g: this and this) are saying, once validated you can use the incoming token to get client information without validating it from the DB.
My question is, how invalid user situation is maintained then? What I mean is, lets say a client just got a JWT token which expires in one week. But for very specific reason lets say we decided to invalidate the user, and don't want the user to access our API. But still that user has a token which is valid and user can access the API.
Of course if we take a round trip to DB for each request then we can validate if the account is valid or invalid. My question is, what is the best way to take care this kind of situation for long lived tokens.
Thanks in advance.
It's difficult to revoke JWT-based access tokens if not impossible.
How should an access token be represented? There are two major ways.
As a meaningless random string. Information associated with an access token is stored in a database table behind an authorization server.
As a self-contained string which is a result of encoding access token information by base64url or something similar.
A choice between these ways will lead to consequent differences as described in the following table.
See "7. Access Token" in "Full-Scratch Implementor of OAuth and OpenID Connect Talks About Findings" for pros and cons of the ways of access token representation.
If your access tokens are JWT-based, your system has to (1) remember revoked access tokens until they expire. Another compromise is to (2) make lifetime of access tokens short enough and give up revoking them.
Personally, after consideration, I didn't select JWT as access token representation when I implemented an authorization server (Authlete) because it is difficult/impossible to revoke and update JWT-based access tokens once they are issued.
RFC 7009 specifies OAuth 2.0 Token Revocation. Basically you have an endpoint where you can revoke the access_tokens.
It's not clear which OAuth flow you are using from your question, or whether you are referring to OpenID Connect rather than Oauth.
Consider using refresh tokens and have a much shorter expiration on your access token - e.g. 30 mins.
In this scenario, the user (resource owner) doesn't have to keep authenticating, and your API (Resource Server) doesn't have to check the user is still valid on every single request.
Once the access token expires, your client (application calling your API) should contact your DB (Authorisation Server) and exchange its refresh token for a new access token - and usually a new refresh token - providing the user is still a valid user on your DB and the user has not revoked access for the client application to his/her data on the API.
You could also use token revocation as suggested in another answer if your Authorization Server allows it but I would try refresh tokens and short-lived access tokens as it's much easier to implement and doesn't pollute your API with user authentication/authorisation concerns - this job is best done by an Auth Server.
That's the main problem when you are using JWT. So basically best approach in this case is creating blacklist on your gateway. It's not best solution for security point of view but this is only good solution if you are using JWT.
Related
I'm creating a REST API to store some information about some items.
It is nothing highly sensitive or anything but I still want to properly secure it. Also in regards of maybe having to secure something else in the future.
To sign the users in I'm using OIDC with Google and Azure to retrieve user information from the user information endpoint. After that I want to store the user in a database along with their permissions. For them to access the API I want to generate and sign a JWT Access Token and Refresh Token. So far so good.
I want the acces to the API to be stateless (with the Access Token) for scalability. I'm not so much worried about the sign in process being stateless. The refreshing of Access Tokens via the Refresh Token also doesn't have to be stateless, but it would be nice to have.
I was reading through some other questions and articles online regarding XSS and CSRF. To me it all boiled down to two things:
Don't use local or session storage to prevent XSS-Attacks grabbing tokens stored there. Solution seemed to be to use cookies (http only cookies, samesite).
Don't use cookies as to prevent CSRF.
I'm now kind of stuck because the two options seem to recommend not using either.
I thought about how this might be solvable and was reading through OWASP recommendations mentioning generating a fingerprint during sign in and storing it in the JWT as user context.
In my mind I have the following process.
Sign the user in using OIDC and receive information about the user from the user endpoint.
Look up the user in the database and get their permissions.
Create a unique fingerprint for the user.
Store the fingerprint in a hardened cookie (http only, secure, samesite).
Create a JWT Access Token using the users id, permissions and an encrypted string of the fingerprint.
Create a JWT Refresh Token using the users id, permissions and an encrypted string of the fingerprint.
Sign both JWTs.
Return the Tokens to the client with the hardened cookie set.
Now if the user wants to access a protected resource he sets the Authorization Header with the Access Token and sends the request, which will then also include the hardened cookie. The server can decrypt the fingerprint from the Access Token and compare it to the fingerprint from the cookie.
If the user wants to use the Refresh Token to get an expired Access Token the fingerprint would also be validated before issuing a new Access Token.
Access Tokens would be short lived e.g. 15 minutes. Refresh Tokens would be long lived e.g. 1 day.
In my mind this solves both problems:
Leaking of the tokens would be useless without also having the fingerprint from the cookie or the cookie itself.
Leaking the cookie via something like CSRF would be useless as the Tokens would not be available.
Only if an attacker would simultaneously get hold of both he would be able to have access.
My questions are:
Am I overlooking something?
What would be a good way to generate this fingerprint? Use the "sub" from the user endpoint?
Thanks for your help already!
Im building a REST services for existing product. Now to authenticate these, there needs to be some mechanism. To give specifications, I have a Db which stores userid and password . I have to authenticate using these credentials.
In above should I use OAuth or JWT? I prefer to use JWT to generate token first and pass token along every request.
Also From my understanding, I understand OAuth should be used when you have multiple consumers like games/apps using Facebook login. In my case, I don't have any have multiple consumers.
Please advise
Although it is true that OAuth is an authorization framework, it does help with JWT. JWT is a token specification, meaning, how you manage and issue tokens is largely left undefined. For instance, when your token reaches it's expiration, do you want your user to be abruptly logged out? By default, if you're using tokens with a certain duration, this will happen if you're checking for expired tokens, which you should be doing.
An OAuth Authentication server can serve the purpose of issuing an Access Token in JWT, and a Refresh Token. The access token will be included in every request, and the refresh token can be used when the access token is expired or about to expire to acquire a new access token. This is useful when taking into account the potential need to revoke a users access to your application. If you set a short access token life, then you'll be able to revoke access more quickly by removing their refresh token.
The technologies are different and not directly comparable because they solve different problems and are intended for different uses.
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.
I am working on asp.net web api 2 and used JWT for authentication. The application is working fine as it generates token on login request from user, and then user can use that token for subsequent request. But I have some security concerns like
What if the token is stolen from user's browser, How can server detect a valid request among two requests sent from two different computers.
When user will sign out, how server can detect that this particular token is now invalid/loggedout. As I read about log out, it is merely deletion of token from client browser, so stolen token will still be there, requesting from other pc.
How can server revoke a token when expiration period reached?
Please comment if my question is not clear.
Please find the answers as below:
1) Access tokens like cash, if you have it then you can use it, if you have valid access token there is no way to identify if the request is coming Authorized party or not, thats why HTTPS must be used with OAuth 2.0 and bearer tokens.
2) Self contained tokens like JWT are not revocable, so there is no DB checks and this is the beauty of it, you need to leave those tokens until they expire. If you used reference tokens then you will be able to revoke them, but the draw back for this approach is hitting the DB with each API call to validate the token.
3) Already answered in part 2.
You can check my series of posts about this topic using the below links:
Token Based Authentication using ASP.NET Web API 2, Owin, and
Identity.
AngularJS Token Authentication using ASP.NET Web API 2.
JSON Web Token in ASP.NET Web API 2 using Owin.
When it comes to JWT revocation the general idea seems to be either that:
it simply can't be done
or it can be done, but it goes against the stateless nature of JWT.
I generally don't agree with either. First JWT is just a token format (Learn JSON Web Tokens), yes it can be used to shift some state from servers to clients, but that does not impose any restriction on what we can and should do to consider them valid from the point of view of our application.
Second, if you understand the implications and the associated cost of implementing revocation functionality and you think it's worthwhile to use self-contained tokens instead of alternatives that could simplify revocation but increase the complexity elsewhere then you should go for it.
Just one more word on the stateless thing, I think I could only agree to it in the remote chance that the application receiving and validating tokens does not maintain any state at all. In this situation, introducing revocation would mean introducing a persistent store where one did not exist before.
However, most applications already need to maintain some kind of persistent state so adding a few more bits to track blacklisted/invalid tokens is a non-issue. Additionally, you only need to track that information until the token expiration date.
Having covered the general theory, lets go through your individual questions:
If your security requirements mandate that you need to employ additional measures to try to detect malicious use of a token then you're free to do so. A simple example would be blacklisting a token if you detect usage of the same token coming from very different geographical locations.
With support for token revocation in place the application logout scenario would just need to include a step to blacklist the associated token.
I may be missing something here, but if the token expiration time was reached the regular process to validate a JWT would already include a check to make sure that the token was not yet expired.
I want to understand what token-based authentication means. I searched the internet but couldn't find anything understandable.
I think it's well explained here -- quoting just the key sentences of the long article:
The general concept behind a
token-based authentication system is
simple. Allow users to enter their
username and password in order to
obtain a token which allows them to
fetch a specific resource - without
using their username and password.
Once their token has been obtained,
the user can offer the token - which
offers access to a specific resource
for a time period - to the remote
site.
In other words: add one level of indirection for authentication -- instead of having to authenticate with username and password for each protected resource, the user authenticates that way once (within a session of limited duration), obtains a time-limited token in return, and uses that token for further authentication during the session.
Advantages are many -- e.g., the user could pass the token, once they've obtained it, on to some other automated system which they're willing to trust for a limited time and a limited set of resources, but would not be willing to trust with their username and password (i.e., with every resource they're allowed to access, forevermore or at least until they change their password).
If anything is still unclear, please edit your question to clarify WHAT isn't 100% clear to you, and I'm sure we can help you further.
From Auth0.com
Token-Based Authentication, relies on a signed token that is sent to
the server on each request.
What are the benefits of using a token-based approach?
Cross-domain / CORS: cookies + CORS don't play well across different domains. A token-based approach allows you to make AJAX
calls to any server, on any domain because you use an HTTP header
to transmit the user information.
Stateless (a.k.a. Server side scalability): there is no need to keep a session store, the token is a self-contained entity that conveys all the user information. The rest of the state lives in cookies or local storage on the client side.
CDN: you can serve all the assets of your app from a CDN (e.g. javascript, HTML, images, etc.), and your server side is just the API.
Decoupling: you are not tied to any particular authentication scheme. The token might be generated anywhere, hence your API can
be called from anywhere with a single way of authenticating those
calls.
Mobile ready: when you start working on a native platform (iOS, Android, Windows 8, etc.) cookies are not ideal when consuming a
token-based approach simplifies this a lot.
CSRF: since you are not relying on cookies, you don't need to protect against cross site requests (e.g. it would not be possible to
sib your site, generate a POST request and re-use the existing authentication cookie because there will be none).
Performance: we are not presenting any hard perf benchmarks here, but a network roundtrip (e.g. finding a session on database)
is likely to take more time than calculating an HMACSHA256 to
validate a token and parsing its contents.
A token is a piece of data which only Server X could possibly have created, and which contains enough data to identify a particular user.
You might present your login information and ask Server X for a token; and then you might present your token and ask Server X to perform some user-specific action.
Tokens are created using various combinations of various techniques from the field of cryptography as well as with input from the wider field of security research. If you decide to go and create your own token system, you had best be really smart.
A token is a piece of data created by server, and contains information to identify a particular user and token validity. The token will contain the user's information, as well as a special token code that user can pass to the server with every method that supports authentication, instead of passing a username and password directly.
Token-based authentication is a security technique that authenticates the users who attempt to log in to a server, a network, or some other secure system, using a security token provided by the server.
An authentication is successful if a user can prove to a server that he or she is a valid user by passing a security token. The service validates the security token and processes the user request.
After the token is validated by the service, it is used to establish security context for the client, so the service can make authorization decisions or audit activity for successive user requests.
Source (Web Archive)
Token Based (Security / Authentication)
This means that in order for us to prove that we’ve access we first have to receive the token. In a real-life scenario, the token could be an access card to the building, it could be the key to the lock to your house. In order for you to retrieve a key card for your office or the key to your home, you first need to prove who you are and that you in fact do have access to that token. It could be something as simple as showing someone your ID or giving them a secret password. So imagine I need to get access to my office. I go down to the security office, I show them my ID, and they give me this token, which lets me into the building. Now I have unrestricted access to do whatever I want inside the building, as long as I have my token with me.
What’s the benefit of token-based security?
If we think back on the insecure API, what we had to do in that case was that we had to provide our password for everything that we wanted to do.
Imagine that every time we enter a door in our office, we have to give everyone sitting next to the door our password. Now that would be pretty bad because that means that anyone inside our office could take our password and impersonate us, and that’s pretty bad. Instead, what we do is that we retrieve the token, of course together with the password, but we retrieve that from one person. And then we can use this token wherever we want inside the building. Of course, if we lose the token, we have the same problem as if someone else knew our password, but that leads us to things like how do we make sure that if we lose the token, we can revoke the access, and maybe the token shouldn’t live for longer than 24 hours, so the next day that we come to the office, we need to show our ID again. But still, there’s just one person that we show the ID to, and that’s the security guard sitting where we retrieve the tokens.
The question is old and the technology has advanced, here is the current state:
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for passing claims between parties in web application environment. The tokens are designed to be compact, URL-safe and usable especially in web browser single sign-on (SSO) context.
https://en.wikipedia.org/wiki/JSON_Web_Token
It's just hash which is associated with user in database or some other way. That token can be used to authenticate and then authorize a user access related contents of the application. To retrieve this token on client side login is required. After first time login you need to save retrieved token not any other data like session, session id because here everything is token to access other resources of application.
Token is used to assure the authenticity of the user.
UPDATES:
In current time, We have more advanced token based technology called JWT (Json Web Token). This technology helps to use same token in multiple systems and we call it single sign-on.
Basically JSON Based Token contains information about user details and token expiry details. So that information can be used to further authenticate or reject the request if token is invalid or expired based on details.
When you register for a new website, often you are sent an email to activate your account. That email typically contains a link to click on. Part of that link, contains a token, the server knows about this token and can associate it with your account. The token would usually have an expiry date associated with it, so you may only have an hour to click on the link and activate your account. None of this would be possible with cookies or session variables, since its unknown what device or browser the customer is using to check emails.