How server verifies JWT token - asp.net-core

How does the server validate the JWT token?
Where is it stored?
How does the token expire after specific days?
On the client side, I store the token and send it to each query. But what's happening on the server side?
It could do with some entry that works

I'm not a JWT expert, so if some of what I write is wrong, I'm very happy to be corrected.
1) When distributing the JWT, the server will sign it using a private key. The private key is top secret, and must be stored securely on the server. This signature can then be verified using a public key, which confirms that this token was indeed signed by the server (using the top secret private key). The public key is not necessarily secret and can be widely distributed to anyone who needs to verify that the token was signed by that server.
2) The JWT does not really need to be stored anywhere on the server, as the server can verify that it's a valid token whenever it receives it. As the server is also likely to generate JWT, some servers will use a cache to store generated and valid JWT to increase performance. So in short, the JWT does not need to be stored by the server.
3) The JWT contains lots of data, including an expiration time (or time when it was created, and duration for how long it's valid). In addition to verifying the token using the public key, the server will discard valid tokens that have expired.
4) Before processing your request, the server will at minimum use the public key to verify that the token is genuine and check the expiration time. If it passes those tests, the server might also do additional checks with the data stored in the JWT before processing your request. These checks might include checking if your user ID has permission to access the data you are trying to access, check if you're located in a country to has access to the data, and so on. It can change wildly from a case to case basis.

It's a little bit of a broad question. I'll try to answer some specific points though.
How does the server validate the JWT token?
JWTs are typically digitally signed.
The token server signs the token using either symmetric or asymmetric cryptography.
The resource server validates the token by checking the signature against the symmetric key or public key.
Where is it stored?
This is up to the client.
In the case of a single page application, the client can store the token in local or session storage.
How does the token expire after specific days?
A JWT always has an expiry time, set in the token when it is created.
And since the token is signed, this time cannot be changed by someone without the key.
The resource server must check the expiry time after validating the signature.

Related

Should a JWT always be verified against the secret that was used to generate it on the server? [duplicate]

This question already has an answer here:
jwt.io says Signature Verified even when key is not provided
(1 answer)
Closed last month.
I'm trying to understand how to use JWTs and more specifically, how not to use them.
Lets say I have a service that lets a user log in with a user name and password and I generate a JWT in response.
Next, the client passes this JWT as part of a request to my API that is located in a separate service. This service can verify that the signature is correct, whiteout knowing the secret key that was used to sign it with. It can also extract the claims.
But what's stopping a malicious user from just generating a JWT using any random secret key for signing, and modifying the claims?
The JWT below is signed using the key "my_super_Secret_key", not the original key that was used by my Identity service. I also changed my username to admin. When my service receives this JWT, it will see that it has a verifiable signature and happily extract the claims.
Should all incoming requests have the JWT verified against the secret key that was used to generate it?
Firstly, your service must always verify the signature in a JWT.
This is to prevent exactly the attack you describe where an attacker creates their own token with any claims they want and sends it to your app.
If you use symmetric cryptography (HS256 in your token is one), you need the original secret to verify the signature.
If you use asymmetric cryptography (e.g. RS256), then you need the public key to verify the token. A private key is used to create the signature.

Does JWT require Access token and refresh token always?

IMHO, there are two ways of signing a JWT token in OAuth2.0 - using symmetric hashing algorithm (like HS256) or using asymmetric hashing algorithm (RS256).
If we use asymmetric hashing algorithm such as RS256, do we require access token and refresh token? I believe they are not required as the whatever the claims present in the payload, the resource server can verify independently (as long as it knows the public key of the authorization server).
Then what is the use case for access token and refresh token? Is it required for symmetric hashing only?
Please help me in understanding this better. Thanks in advance.
The main idea of access token as JWT is that you don't have to go to the Authorization server every time. You can validate it by yourself by checking the signature. This can remove a lot of traffic from the Authorization server / DB.
You will want to use asymmetric hashing algorithm so the issuer has the private key and he is the only one allowed to issue the tokens and you can check the JWT with the public key.
The refresh token is what validated against a DB and can be revoked.
Every time the access token is expired you use the refresh token to get a new access token from the issuer.
If you plan on going to the Authorization server every time you want to check if the access token is valid, you can use symmetric hashing algorithm but then you miss the point of the JWT - you still have central place for all the authorization requests.

What is signed authentication token?

Currently I'm learning about JWT and started with the token based authentication. I don't understand the sentence from the article:
Token based authentication works by ensuring that each request to a
server is accompanied by a signed token which the server verifies for
authenticity and only then responds to the request.
What is signed token? What does it mean to sign a token? I can't find the question on SO.
A signature is something that can be verified.
The main problem you're trying to solve is this: the server creates some arbitrary value, the token, which it gives to the client. The client subsequently gives it back to the server as proof of something (proof that they're authenticated, for instance). Now, how can the server be sure that the token is genuine, and the client didn't just make it up?
That's where the signature comes in. It's part of the token, and the server can verify that it had previously created that signature, and that the signature was created for this particular token. In a nutshell, the signature is a hash of the contents of the token plus a secret only the server possesses; to verify the signature the server repeats the hash of the token's contents and the secret only it has, and if it matches, that means the token's signature must have been created the same way which assures the two desired attributes of authenticity.
For the gnarly details of how a JWT signature is computed specifically, read the specification.

JWT Token for distrubuted system running on multiple server instance

I am using JWT token for rest api's security.
When user is logged in check user's credentials with DB.
If it matched we are encrypting it for further security and then passing it to jwt to create a token
Now in order to match user's token we need to keep password somewhere so that we can match them when user sends any request after logged in
we can do it 2 ways
1. Keep detail in Database and each time rest call is fired check token with token in Database which is too costly for each rest call
2. Preserve secret somewhere in JVM and use it. Here I have tried HttpSession from package
javax.servlet.http.HttpServletRequest
// My key issue code
// Encrypt it
Key key = keyGenerator.generateKey(password);
jwtToken = Jwts.builder()
.setSubject(username)
.setIssuer(uriInfo.getAbsolutePath().toString())
.setIssuedAt(new Date())
.setExpiration(toDate(LocalDateTime.now().plusMinutes(1)))
.signWith(SignatureAlgorithm.HS512, key)
.compact();
// Adding details to session
HttpSession httpSession = currentRequest.getSession();
httpSession.setAttribute("userSecret", password)
This works fine for single Server instance.
But at some point we need to scale up and run multiple instance of server.
How do we handle this case where user may logged in using 1 instance and may serving rest call using another instance using load balancing.
As users secret is available only in first Server's JVM.
You can share the private key, which was used for encrypting the JWT, among the servers. When a servers gets an API call, you can try to decrypt the JWT with the private key. If the decryption is successful, you have a valid a JWT and you can process the request. If the decryption fails, that means it's an invalid JWT. Once a JWT has been created, you don't need to hit the database. That's the primary usage of JWT in my opinion.
I am not sure what you mean by userSecret.

how does token validation works on token based authantication systems

When token based authantication is compared to traditional server authantication, it is said that: traditional method keeps login info in memory on server side, but in token based authantication server keeps nothing. Information about logged in user is stored in token itself.
However, I didn't get one point here. If server doesn't store anything, how does server validate the token? I think it should store the secret key to decrypt the token and then validate.
If so, where is it stored? If not what poin did I miss?
The server issuing the token, digitally signs the token with a private key.
The service consuming the token only needs the public key to validate the token. It can download the public key from the issuing server on startup or first use. After that, it does not need to communicate with the issuing server to validate tokens. If the signature is valid, the service trusts the contents of the token.
For example, look at the "jwt", it uses "ssh" keys