How Does The Server Know If A Bearer Token Is Valid Without Storing It On Disk Or Memory - rest

So I just implemented token based authentication in a Web API app using OWIN and I was able to understand the concept of how it all works (well on the surface at least).
What I couldn't understand is how the server validates the generated bearer token without storing it on the disk or memory. I mean sure the expiration date is probably encrypted in the token itself, but that only applies if it is already expired. So how does the server do it (on a high level)?
Update:
Okay i can see that the claims are stored in the token.So at some level the server is still checking that with the db during authentication correct? Otherwise let's assume that i'm the server and I was able to decrypt the token to this object:
{
"iss": "thesite.com",
"exp": 1300819380,
"name": "Chris Sevilleja",
"admin": true
}
So the question now is does the fact that I (the server) was able to decrypt the token into key value pairs (checking for the presence of specific keys like 'iss', 'exp' and checking for values like the 'admin' key must be true) means that I will authorize the web request?

JWT token is made up with three parts separated by dot(.).
First part is Header.
Second part is Payload
Third Part is Signature (say s0)
JWT Format
Signature is created using Header and Payload.
When server receives JWT token it creates temporary signature (say s1) from incoming header and payload.
If s0 and s1 signatures are same then token is valid.
Also token contains claims which are used to validate token. e.g exp claim contains unix epoch time after which token is considered as invalid.

The token is encoded with the JWT format (JSON Web token). This is well described in the standard (https://www.rfc-editor.org/rfc/rfc7519) and you will see that the token contains a certain number of claims, among which the expiration date (exp).

Related

Can I use a globally unique userid for 'sub' claim in OIDC ID Token?

I'm having hard time understanding OIDC that I'm asking here.
[Current Understanding]
ID Token (Based on JWT)
[REQUIRED]
iss (Issuer) : OPurl
sub (Subject Identifier) : unique identifier
aud (Audience) : Unique Client ID which OP provides beforehand
exp (Expires at) : When token expires
iat (Issued at) : When token is issued
[OPTIONAL]
nonce : string value used to associate a client session with ID token (REQ for Implicit Flow)
preferred_username : Shorthand name by which the End-User wishes to be referred to at the RP (The RP MUST NOT rely upon this value being unique)
Sample Token
{"access_token":"SlAV32hkKG","token_type":"bearer","expires_in":3600,"id_token":"eyJ0...","refresh_token":"8xLOxBtZp8"}
Authorization Code Flow (/authorize GET => /token POST) : contains refresh_token and is in JSON form
Implicit Flow (/authorize GET) : does not contain refresh_token and is responsed in fragment mode
Sample ID Token
Header (Base64 Decoded) : {"typ":"JWT","alg":"RS256","kid":"sdfikhRETlknsdfollksdf324lhk"}
Payload (Base64 Decoded) : {"iss":"OPurl","aud":"ClientID","sub":"1234567890","exp":"1665666710","iat":"1665666790"}
Signature : ggW8hZ...zqg
[Question]
In OIDC Core Spec, sub(subject identifier) is a "locally unique and never reassigned identifier within the Issuer for the End-User, which is intended to be consumed by the Client".
In JWT Spec, it can either be locally unique in the context of the issuer or be globally unique.
Here I have a globally unique User ID. (Let's say 1234567890)
User uses this ID for client A, B, C... everywhere.
No others can use this ID.
Can sub be that ID itself? ("sub":"1234567890")
Or Should sub be like a mix of a random string with the id and preferred_username should be the ID itself? (Keycloak for example, returns the token like {"sub":"f:636436-348762gyu-234786234:1234567890", "preferred_username":1234567890})
I'm not really sure what it means to be "never reassigned identifier within the Issuer for the End-User"...
Any help would be appreciated.
Please let me know if my current understanding is wrong!
I am going to answer with the assumption you are the developer of a JWT producer.
Based on your comments you may also be the developer of the JWT consumer, which makes me wonder why you are choosing OIDC/JWT for this single identity flow. Either way I will respond with context of producer where the consumers are multiple identities authenticating with you, an identity provider, and you are simply coding the OIDC as an JWT producer.
Here I have a globally unique User ID. (Let's say 1234567890)
This is not appropriate if:
a) this user input of any kind (they register their own username)
b) the user may edit (or request an edit) to the value, e.g. an email address or user handle as a username
c) the numeric example it taken literally, the identifier should not be sequential or attackers can enumerate them easily.
It is common the aud and sub are kept associated in server persistent state, and later the JWK identifier (kid) will be set from the key alias (aud or sub for consistency and simplicity) in the store.
Therefore it is quite important to make the sub immutable, server generated, and this will help you to never orphan a key that would cause significant issues in practice.
It means that the subject identifier is a value that should never ever change.
It should be a unique value within your system.
Unlike preferred_username or email or name.

Why is 'id' called 'sub' in keycloak?

Im looking at the new Keycloak Beta 4 API. When i get the users account information, what is referred to as 'id' in the web ui comes back as 'sub' in the account object.
{ sub: '25a37fd0-d10e-40ca-af6c-821f20e01be8',
name: 'Barrack Obama',
preferred_username: 'obama#whitehouse.gov',
given_name: 'Barrack',
family_name: 'Obama',
email: 'obama#whitehouse.gov' }
What is 'sub' and is this a safe uuid to map database objects to?
As per the keycloak documentation
Anatomy of Action Token
Action token is a standard Json Web Token signed with active realm key where the payload contains several fields:
typ - Identification of the action (e.g. verify-email)
iat and exp - Times of token validity
sub - ID of the user
azp - Client name
iss - Issuer - URL of the issuing realm
aud - Audience - list containing URL of the issuing realm
asid - ID of the authentication session (optional)
nonce - Random nonce to guarantee uniqueness of use if the operation can only be executed once (optional)
Please refer the following link https://www.keycloak.org/docs/latest/server_development/index.html#_action_token_anatomy
Reason may be they want to retain the uniqueness in the name.
In addition to the previous answer, inside JWT tokens, sub refers to subject. The reason is that those tokens can be used in various cases, including authorization. That means that id sometimes might not be "the unique identifier" but might be anything, including repeatable destinations. Basically, a naming convention JWT follows, regardless of Keycloak.

Why does Spring's default OAuth JWT implementation make the JWT verifier public?

Spring's default OAuth JWT flow (using client_credentials grant) is as follows:
Launch the Auth Server (AS)
Launch the Resource Server (RS)
At startup the RS requests the tokenKey by calling GET /oauth/token_key using Basic Auth
The AS returns a PUBLIC KEY using RS256 (SHA256withRSA)
Some time later, the Client requests an accessToken by calling GET /oauth/token using the client_credentials grant
The AS returns a JWT accessToken containing a JWS signature
The Client sends the JWT as a Bearer token to the RS
The RS uses the tokenKey that it received from the AS at startup to verify that the JWT accessToken came from the AS. This is where I get confused...
Is this secure? Why would a public cert be used rather than a shared secret key? Couldn't a hacker easily obtain the public key and sign their own valid JWT accessToken? How does the usage of the public key cert and the JWT signature work together to verify that the sender was actually the Auth Server and not an attacker?
Any insight would help.
Some research into the nature of public key cryptography and digital signatures gleans this:
Digital signatures implement asymmetric cryptography. A digital signature gives the receiver reason to believe the message was sent by the claimed sender. Similar to a handwritten signature they are difficult to forge. The signer, in this case, the AS, uses a secret PrivateKey to create the signature. Some non-repudiation schemes offer a time stamp for the digital signature, so that even when the PrivateKey is exposed, the signature is valid.
A digital signature scheme typically consists of 3 algorithms
1) A key generation algorithm that selects a PrivateKey uniformly at random from a set of possible private keys. The algorithm outputs the private key and a corresponding public key.
2) A signing algorithm that creates a signature using the message and the private key
3) A signature verifying algorithm that, given the message, PublicKey and signature, either accepts or rejects the message's claim to authenticity.
In this case (RS256), the signature was created using SHA256withRSA which is not used as an encryption algorithm, rather it is used to verify the origin or the authenticity of the data. The signature was generated using a private key. The public key is passed to the Resource server to be used to verify the signature. In this scenario, even if an attacker has the PublicKey, they cannot create a spoof message with the signature or alter the contents.

Should two JWTs still be considered equal if their claims/headers are in different orders?

If I have two JWTs, where their set of claims and headers are the same but the order they are stored in json is different, should they be considered equal?
Clarification:
I am aware that as a user of JWTs you should not need to compare them, but that is not what I am doing.
Say we have some jwt library, and you have some object that represents a JWT in it's decoded form. If we create an encoded JWT from our decoded JWT and then apply it to some function that returns once again the decoded JWT. Do we consider the two decoded JWTs to be equal if the order in which the claims or headers are stored in some collection has changed due to the decoding process?
Thinking more about this, perhaps it is wrong to store the headers and claims in a collection which has some notion of order? Using something like a set makes this problem disappear?
Depends on what you mean by 'different'. If the claims are the same then they are the same in the sense that the information transferred is equal. But if they both have the same signature then at least one will be invalid.
Also you shouldn't need to compare JWT claims at all. If you're storing the token and comparing the token given then you should revisit why you're using JWT over something like session.
JWT is designed to be independent. Because JWT tokens are claims based authentication the validation is done against the signature, not against anything on the server.

RSA authentication and CSRF attacks

If I use RSA authentication for my web app would I still need to take care of CSRF attacks by using tokens or RSA authentication will take care of it.
that depends on your implementation ... rsa itself has nothing to do with csrf ...
an authentication schema can provide some protection (for example if you let the user sign all of it's inputs), but honestly: what's the deal with protecting user inputs from csrf?
on the server side, on login create a salt stored within the users session, calculate hash(current_timestamp, salt) everytime you need to protect a user input, and give that value + the current_timestamp as hidden field to the form ... when you receive the user input, get the salt, and recalculate the value ... if that one matches with what you got from the client, it is unlikely that the input came through csrf ...
since you never expose the salt to the user, there is no way (except taking it directly from your session database which means a compromised system) for the user or an attacker to obtain that salt ...