Identityserver3 Update Permissions - identityserver3

I wondering if i could update the current user claims w/o the user having to authenticate again.
In my case the user will log into the application and will receive a set of claims. Later he will be able to change the customer his working with. Once that is done he need to receive a new set of claims.
Does any one know if that can be done?
Thanks in advance.

You almost answered your own question - a token is not a good place to store permissions, because the only way to update the token content is to get a new token.
Tokens are good from transmitting immutable identity data. Everything else belongs into the realm of application or business logic design.

Related

How to prevent log out users when changing JWT secret?

I am using a JWT token implementation of this https://jwt-auth.readthedocs.io/en/develop/quick-start/
I need to update the secret key and is there a way to update it without logging out every user? I presume it's not possible to reuse the old token once my secret key is changed. So all my users will be logged off and need to log in again. Is there any way to go around this?
If not, if for security reason, I need to update the secret monthly, that will be pretty troublesome to ask my user to re-login monthly.
Thanks!
If you change your keys it's correct to invalidate all the tokens signed with the old ones as they are to be considered expired.
It's a good practice to let the token expire as well after a certain amount of time. Usually you implement a mechanism based on two tokens, access_token with an expiration of 1h (usually) and a refresh_token with a longer expiration (usually 24h). The second one is used to renew the first one. When the second one expires, the user has to be considered logged out.
What you need is to implement a refresh token mechanism. You can implement it from scratch, for learning purposes, or you could just implement OAuth 2.0 protocol, since it's a flow that it already supports. There are lots of libraries both for server side and client side implementations
https://oauth.net/

JWT logout feature without using blacklist?

I have used JWT before, but they were API that didn't need logout feature.
I need to implement logout feature for a API of an android app and SPA. When I looked it up I found that there are two ways to do it.
the easiest way is to delete the JWT Token from client side and call it a day.
The logic behind this is that since no session of any kind is maintained in server deleting the token in client side should be enough.
But it still leaves the possibility that, if the token falls in wrong hands they can still use it even after the user is no longer using the token.
Given if the app is well designed and uses HTTPS then chances of this happening is very low and can be minimized by keeping the valid time for the token short. But in my case the tokens are valid for 30 days.
the second option is to maintain a blacklist of tokens in server side
This solves the problem of the token still being usable even after user has logged out and stopped using it.
But it adds a complication of needing to run a cronjob to remove expired token form the blacklist table. Otherwise the table will eventually become ridiculously large.
It also kinda defeats the point of using JWT. Maintaining blacklist is very similar to maintaining session. We have to run an additional db query for every request. And it scales badly, as the no. of users grows the no. of token that needs to be blacklisted will also grow (this will be a bigger problem for API like mine with multiple front end apps and long validity period for the tokens).
Then I got an idea for third way.
Add jwt_secret row in user table that stores randomly generated string. Use it to sign the JWT Token then on every request use user id in the jwt payload to get the user form db(which is not an extra query, we have to do this anyway) and validate the token signature using jwt_secret of the user. When the user logs out we change the jwt_secret which makes all token out there useless.
At first I thought this was a great solution only to realize that in this setup if user logs out of one device or browser he/she gets logged out of all devices.
So is there a another option? Or a way to modify any of above approach to solve the problem. Or am I over thinking this and one of the above option should be used?
For logging out, which as you pointed out is a user initiated action, I don't think you need to do anything extra. If the user somehow did not delete his JWT, then so be it. He wouldn't be getting any extra access over to what he is already entitled.
However, your question seems to hint on the problem of how to know that a JWT is valid. Again, as you pointed out, if a JWT somehow fell into the wrong hands, then there may be no avoiding this. But, with each request you would typically be doing several types of validation against that JWT, e.g.
checking the claims of the JWT, such as the token expiry date
assuming the claims pass, then checking that user's ID against your database table to make sure the account is active, has not been suspended, etc.
My point here is that if you need to keep track on the server side that a logout has happened, you might need to persist this to a database. But, I don't think you would need this.

JWT authntication and its alternatives to reach RESTfulness of web application back-end

In my company, we are building a web application and most actual problem is to pick an authentication solution. Im thinking about 3 of most used way to maintain
session with authenticated user: stateless JWT (all session data holds JWT token in its payload), stateful JWT (token is only used to validate requests and in its payload it has session ID to session data record at server) and traditional session ID stored in cookie, which requires additional check for matching id in server.
Because i want to build this app RESTful, only first way seems right to me. This way a server does not need to hold any state.
My first question is: Is it ok, to store all session data in token payload (of course, those data are not that big and they are not supposed to be a secret, hence no security is needed).
Also, im going to implement logout logic as well and i know, that blacklisting tokens, which is in my case, i think, best solution ruines statelessness too.
Do you know of any other way to implement logout logic which IMMEDIATELY invalidates JWT token ?
Thank you for your answers.
EDIT:
In case of invalidation, im thinking about sending an updated token with either a flag which tells "im invalidated token" or with expired expire date. This solution but works only for "good boy" users. Hackers will keep previous and still valid token.
Logout with JWT works by deleting the token client-side. Like this.
function removeToken() {
localStorage.removeItem("jwt-token");
}
Without the token, the user is logged out. So I think it is immediate?

Is "logout" useless on a REST API?

Considering that, by definition, a REST API is stateless: is the "logout" operation useless?
I mean, I'm creating a REST API using encrypted JWT. Each token has an expiration time of, let's say, 60 minutes. If I save on a database table the last tokens generated by the API, the "logout" would be done deleting them from the table of valid tokens. But, if I do that, I understand that the API will cease to be stateless, right?
So, I understand that I shouldn't do that. The only solution that I'm thinking is make the JWT expiration time shorter, to 5 minutes, don't implement a "logout" operation and just let the tokens expire.
Is this the correct approach?
I mean, I'm creating a REST API using encrypted JWT
The JSON Web Token (JWT) tokens encodes all the data about the grant into the token itself. The most important advantage of this approach is that you do not need a backend store for token storage at all. One disadvantage is that you can't easily revoke an access token, so they normally are granted with short expiry and the revocation is handled at the refresh token. Another disadvantage is that the tokens can get quite large if you are storing a lot of user credential information in them. So if:
If I save on a database table the last tokens generated by the API,
the "logout" would be done deleting them from the table of valid
tokens
Then you would lose the most important advantage of using JWT and also, still have all those disadvantages, which seems unreasonable to me.
So, I understand that I shouldn't do that. The only solution that I'm
thinking is make the JWT expiration time shorter, to 5 minutes, don't
implement a "logout" operation and just let the tokens expire.
Is this the correct approach?
In my opinion, if you're planning to use JWT, YES! it's better to rely on the token expiration. For more details on this approach you can check this question out.
Is “logout” useless on a REST API?
Regardless of the fact that you're using JWT and similar to any other decent questions on computer science, the answer would be It Depends. The most important advantage of Statelessness is that your API would be more scalable. If you choose this path, probably, every request on your API should be authenticated, since you may need to search a backend store for the given token or decode a JWT token. So, in this case you may have some performance cost on a single node but in a big picture, you would still have the scalability. I guess what i'm trying to say is, if you do not need that scalability, you're better off to choose a Stateful approach. Otherwise, pure REST principles is the way to go.
Automatic token expiry is a separate concern from an explicit "log out" mechanism and, as such, they are both perfectly valid actions regardless of whether your API is ReSTful or not.
When a user logs out they are making a conscious decision to invalidate their access token - for example, if they're using a public computer or borrowing someone else's device temporarily.
Automated expiry is used to ensure that the user must revalidate, in some fashion, on a regular basis. This is good for server-side security.
Access tokens are not about sharing session state between client and server - it's entirely possible to implement an access token system without shared state and the token itself doesn't implement session state, it's only used to verify that the user is who they claim to be. As such, access tokens are not really anything to do with the statefulness of the API.
I think it depends on the behavior that you want for your application, and how secure you need it to be. Do you really need to invalidate the token?
For instance, you could just remove your token from your frontend (browser or app). In theory, it is the only place that stores that particular token. If the token is compromised, it will still be valid until it expires, though.
If you really need to invalidate it server side, a common approach would be to create a blacklist with the token, and clear the expired entries from time to time.
But what if you need your application to accept just one token for each user, like in a bank app that you can only be logged in one device at time? For that purpose the blacklist won't do the job, so you will need to store a single token for each user and check if the passed token is the same. At logout, you would just clear that unique entry. Or you may just use sessions.
So, it is not useless, It just depends on your application.
I would argue that your API is already stateful just by the sheer fact that you have a token around. I also wouldn't get too hung up on REST purity, meaning that everything has to be stateless come hell or high water.
Put simply, if your application requires login, then you need a way to logout. You can't implement a short expiry because that's just going to be a really annoying experience to consumers of the API. And you can't just have no logout at all, because thats a potential security flaw.
I have a similar REST API that I support and I implemented a logout endpoint that is a DELETE call. It simply deletes the token information on the server side and clears any type of authentication for the logged in user.
TL;DR
No, a logout is not useless in a REST API. In fact, for APIs that require authentication, it is more or less a necessity.
With a short expiration time on the token I would think for most applications deleting the token from the client on logout would be a good solution. Anything more would rely on the server and no longer be stateless.
The good solution here would be to delete the token from the user.
So typically when you log in, you will get back a token from the server and store it in localStorage or sessionStorage (depending on the user wanting to be logged in after closing the tab) in the browser, and then send the token from there in the headers with any request that you make to your api.
Then if the user logs out, you don't even contact the api (you don't make any requests to your server), you just clear the sessionStorage or localStorage, use the command localStorage.clear() or sessionStorage.clear() , and then if the user will want to send more requests, he'll have to login again in order to get another token.
One drawback to this approach is, that if a virus, for example gets the token from the local or session Storage before the user logs out then, it will still be able to send requests as you, as the token will still be valid.
One solution to that would be to create a token blacklist in the database, and store the token there if the user logs out, until the token expiration time. However, every time the user would request something, the database would have to be consulted to check if his token is blacklisted, lengthening the process, and making your API stateful.
You can generate a new token that it already expired i.e. expiration is 1sec. and pass it to the user. Any upcoming request will be invalid. This is not optimal solution though..

Is it Safe/Good practice to save global values in NSUserDefaults?

I am making an IPhone app in which
userid and password is required in
all the screens to make requests to
the server, and I am thinking of
saving those 2 values in
NSUserDefault instead of passing an
object around.
I am also thinking it will be useful if user has logged in once,
and use the app again then user
don't have to enter his/her details
again.
But I am curious if it will be safe/good practice to use for first requirement?
I don't have anything against save these data on the user defaults. What I don't get is the idea to expose the user credentials on each request.
I would suggest you to ask for the credentials once, authenticate with your server and return a "session token". save this token and use it to validate the user on each request. (it means that you will save the token on you server or you will check the token using an algorithm)
Doing this you don't expose the user credentials all the time, you have control over the session, and you can expire it when you want, forcing the user to logging again.
For more complex implementations, you could Google for OAuth or XAuth and some related methods of authentication.
Cheers,
vfn
It's reasonable to save global values in NSUserDefault that you want to survive your app being killed and restarted (as can happen under iOS4.0).
Passwords should be saved in memory (maybe a singleton model object), or in the keychain, as various iTunes backup databases might expose stuff stored in user defaults.