Asp. Net 5. Jwt tokens revocation - c#

I am using jwt tokens middleware and Asp.Net.OpenIdConnect.Server in my app. In fact, it works fine. But I am confused in one thing. If I use tokens, I can not immediately grant new claims or ban my users. For example. I give my user access token, which expires through 2 days, and refresh token, which expires through 2 weeks. Then I give to this user admin rights. But he will know about this only through 2 days, when his current access token expires, and auth server will give him new token, using refresh token. How can I give him new rights immediately, on the next request?
I understand, that I need to check database for every request, and give to user new access token, if needed . But where should I do it in aspnet 5? Maybe there are some good practices for such thing?

One way doing it is to put a unique identifier into your claims, which you can query to see if it's still valid. You can use the memory cache to store it or some distributed memory cache such as Redis, so you don't have to hit the database every time.
When you ban the user or add a token, you mark this token as invalid by removing it from the cache. Each time you the user refreshes the token, it you should create a new unique id inside the token.

Related

Check Validity of JWT on identity server

My WSO2 Identity Server issues a JWT, and on my .net core backend, i would like to reach out to Identity Server check the token (perhaps it was revoked for example)...
How do I do that?
Start by checking why you would do that. ANY sensible scenario for this WILL HAVE to involve caching. Which is what a token is.
What we do is this:
* You get 2 tokens, an accesToken and a refresh token.
* The access token is accepted on the backend without questions. It is valid 5 minutes.
* The refresh token is doing a full account check. Revoked? no new access token for you.
Doing exactly the same thing without checking ;)

Refresh identity token from client from code

I am using the fine-uploader with an asp.net mvc backend to upload files directly to an azure blob-storage. The asp.net-server works as the azure-signature-endpoint(sas). This is all secured with an identityserver3 and here comes the problem: The identity_tokens lifetime is set to 5 minutes(as default). And I want the SAS endpoint to be only called authorized. So a user can only access its own data. But after I have the upload running for the set 5 minutes, it breaks. Of course, because it is not authorized and it returns the login-page from the identity-server(which the fine-uploader, of course, can't handle).
It would be easy to solve this problem, by either setting the lifetime from the token to something higher(but this is unreliable as the upload could take hours or days), or disable the lifetime(yeah would work. But I guess the lifetime has a reason to exist).
So my 2 ideas would be:
to just authorize the user once(when he starts the download)
or to refresh the token by code every time the signature gets generated.
First approach
Can I just set a boolean like user is authorized and if this boolean is set just skip authorization and just return the signature or how could I achieve this
Second approach
How would I do this?
Don't use the id token for API access, an instead use access token. Access tokens are for resources (APIs), whilst id_tokens are purely for authentication. The id_token is only meant to be used to provide the RP with means of knowing who the user is - hence no need for long time span. It's only there for converting into a user session (cookie/principal).
With access tokens you have several approaches for keeping a valid token at a client; either by fetching new ones using the client credentials flow or by using the refresh token approach.
I believe there are samples of both in the samples repo of IdentityServer.
Samples repo link

How does AntiForgeryToken work behind the scenes?

I know the basics of CSRF and AntiForgeryToken.
I also know that there are many similar questions around but none seemed to describe the implementation details, which is the part I'm interested in.
Each time you call Html.AntiForgeryToken(), it generates a new random token :
Can I have multiple active tokens at the same time? (I assume it's yes here)
Can I use any of those tokens in another form? (I assume it's yes here)
Can I use the same token more than once?
Is there a security reason why the token is random everytime? Couldn't it be the same token for the whole session?
The token is stored in a cookie
When I have multiple forms and tokens in my page, does it mean I have multiple cookies or only 1 cookie containing all the active tokens?
Also...
How is the token generated and is it possible to validate it manually.
1.Can I have multiple active tokens at the same time? (I assume it's yes here)
-> Yes.
2.Can I use any of those tokens in another form? (I assume it's yes here)
-> Yes.
3.Can I use the same token more than once?
-> Short answer is yes you can. Long answer: It depends on multiple factors, you would have to regenerate the token if,
Your cookie expires
Your user identity has changed.
Your additional data provider has decided that your token is no
longer valid.
4.Is there a security reason why the token is random every time? Couldn't it be the same token for the whole session?
-> You don't want anyone to be able to predict your token. Remember there is no inbuilt auto expiration of the cookie token.
1.When I have multiple forms and tokens in my page, does it mean I have multiple cookies or only 1 cookie containing all the active
tokens?
-> At any given point of time there would be only one cookie that will be active for a session,
that cookie has a SecurityToken property. Every valid anti-forgery token on the page would have the same SecurityToken (otherwise it would fail validation).
1.How is the token generated and is it possible to validate it manually.
I would suggest to read the post explaining the internals here
and code here
I am actually thinking why would you need to use the same anti-forgery token across forms.. it might be helpful if you share your scenario.
For you last question, you can validate AntiForgeryTokens with the following:
System.Web.Helpers.AntiForgery.Validate(cookie.Value, formValue);
Answering in terms of ASP.NET Core just in case anyone stumbles upon this post from Google.
The following is based off this article:
Can I have multiple active tokens at the same time?
Yes. If you have two tabs open and hit the same URL that returns to you a page with a form containing an antiforgery token, you'll have a different token in the HTML on each page. But you'll have the same token in your cookie.
Can I use any of those tokens in another form?
Yes. You can test this by hitting the URL in two tabs, open Developer Options and swap out the tokens, and the application won't know any better.
Can I use the same token more than once?
Yes. As long as the token in the HTML was generated along with your cookie, then if you're using the same cookie, you could use the same token in your HTML as before.
Is there a security reason why the token is random everytime? Couldn't
it be the same token for the whole session?
See the accepted answer by Harsh Gupta.
When I have multiple forms and tokens in my page, does it mean I have
multiple cookies or only 1 cookie containing all the active tokens?
See the accepted answer by Harsh Gupta.
How is the token generated and is it possible to validate it manually.
Here is a summary from the article I linked above:
Build a byte array using a random number generator.
Generate a unique array based on step 1.
Encrypt the array.
Prepend a magic header and the defaultKeyId to the encrypted array.
Base64URL encode the encrypted array and use this as the token
string.

Restrict concurrent login - ASP.NET Identity

I am trying to only allow a user account to be logged in, only once at the same time.
E.g. User logs in via the browser on their computer, now they cant login at the same time on their phone as they are already logged in.
I can add a bool property to my user entity, that I can update when the user logs in and logs out.
However, I am using SlidingExpiration on the authentication cookie, therefore when the cookie expires it doesn't update my user property to say they are now logged out.
ExpireTimeSpan = <time period>,
SlidingExpiration = true,
Are there any better approach to restricting concurrent login?
Thanks
Can you generate a Token at log in and store it in Data base?
Then, check every time if the token matches with the one provided by user.
If he does log in in another device, the token will be overwritten and won't match with the first one, so the first session will become invalid.
EDIT:
As you asked in a comment, it doesn't block a user to perform a second log in in another device concurrently, it only invalidates the previous sessions.
Avoiding a second log in requires more job and isn't as safe as the method shown above.
Imagine that the user closes the browser without performing a log out... It will block the session.
An approximation of what you want will be adding the time parameter to your log in (adding it into the data base too, and updating the field on every user's action).
Then show the message of "you can't log in twice" if the token doesn't matches and the time span is not far enough (i.e. 5 minutes). But in my example you need to show a "your session expired" if the token has changed anyway.
"The idea is very simple every time the user logged in you have to generate random token , then you should save that token in the database and in session or if you are using Microsoft form authentication you can save it in the ticket, then each time the user request a page you’ll check if the session token is same as database token , if not kick him out!"
http://engthunder.wordpress.com/2011/10/19/preventing-multiple-user-from-logging-in-using-the-same-username-single-user-login-at-a-time/

authorization: what is the flow for non-first time user?

I have a site (still on localhsot).
I want to authorize the user against Google and get permission to gmail scope.
I get a requestToken
Authorize it
Save requestToken from the queryString into a cookie (?)
(I don't have accessToken by now)
Upgrade it to accessToken
Then what?
I thought to save requestToken and accessToken in the DB with some user guid (?)
Are they both parmenent and uniqe?
Will it help next time to avoid the Upgrade it to accessToken
When the user come back for the second time - how will I retrieve its access token?
You will have to store the access token with the user data, yes. Then you will set the Forms Authorization cookie as normal against their username or id.
When they come back a second time, if they still have the cookie, then they will be signed in as normal.
If their cookie has expired, ask them to log in with their chosen provider (Google) and retrieve the token again. You will then have to search the data to see if any users have that token already, and if they do, log that user in as normal like you do the first time.
If they log in with a different provider, they will get a different token and will effectively be seen as a different user - how you handle this is a separate issue.

Categories