Jwt payload not encrypted [duplicate] - c#
If I get a JWT and I can decode the payload, how is that secure? Couldn't I just grab the token out of the header, decode and change the user information in the payload, and send it back with the same correct encoded secret?
I know they must be secure, but I just would really like to understand the technologies. What am I missing?
JWTs can be either signed, encrypted or both. If a token is signed, but not encrypted, everyone can read its contents, but when you don't know the private key, you can't change it. Otherwise, the receiver will notice that the signature won't match anymore.
Answer to your comment: I'm not sure if I understand your comment the right way. Just to be sure: do you know and understand digital signatures? I'll just briefly explain one variant (HMAC, which is symmetrical, but there are many others).
Let's assume Alice wants to send a JWT to Bob. They both know some shared secret. Mallory doesn't know that secret, but wants to interfere and change the JWT. To prevent that, Alice calculates Hash(payload + secret) and appends this as signature.
When receiving the message, Bob can also calculate Hash(payload + secret) to check whether the signature matches.
If however, Mallory changes something in the content, she isn't able to calculate the matching signature (which would be Hash(newContent + secret)). She doesn't know the secret and has no way of finding it out.
This means if she changes something, the signature won't match anymore, and Bob will simply not accept the JWT anymore.
Let's suppose, I send another person the message {"id":1} and sign it with Hash(content + secret). (+ is just concatenation here). I use the SHA256 Hash function, and the signature I get is: 330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c. Now it's your turn: play the role of Mallory and try to sign the message {"id":2}. You can't because you don't know which secret I used. If I suppose that the recipient knows the secret, he CAN calculate the signature of any message and check if it's correct.
You can go to jwt.io, paste your token and read the contents. This is jarring for a lot of people initially.
The short answer is that JWT doesn't concern itself with encryption. It cares about validation. That is to say, it can always get the answer for "Have the contents of this token been manipulated"? This means user manipulation of the JWT token is futile because the server will know and disregard the token. The server adds a signature based on the payload when issuing a token to the client. Later on it verifies the payload and matching signature.
The logical question is what is the motivation for not concerning itself with encrypted contents?
The simplest reason is because it assumes this is a solved problem for the most part. If dealing with a client like the web browser for example, you can store the JWT tokens in a cookie that is secure (is not transmitted via HTTP, only via HTTPS) and httpOnly (can't be read by Javascript) and talks to the server over an encrypted channel (HTTPS). Once you know you have a secure channel between the server and client you can securely exchange JWT or whatever else you want.
This keeps thing simple. A simple implementation makes adoption easier but it also lets each layer do what it does best (let HTTPS handle encryption).
JWT isn't meant to store sensitive data. Once the server receives the JWT token and validates it, it is free to lookup the user ID in its own database for additional information for that user (like permissions, postal address, etc). This keeps JWT small in size and avoids inadvertent information leakage because everyone knows not to keep sensitive data in JWT.
It's not too different from how cookies themselves work. Cookies often contain unencrypted payloads. If you are using HTTPS then everything is good. If you aren't then it's advisable to encrypt sensitive cookies themselves. Not doing so will mean that a man-in-the-middle attack is possible--a proxy server or ISP reads the cookies and then replays them later on pretending to be you. For similar reasons, JWT should always be exchanged over a secure layer like HTTPS.
Let's discuss from the very beginning:
JWT is a very modern, simple and secure approach which extends for Json Web Tokens. Json Web Tokens are a stateless solution for authentication. So there is no need to store any session state on the server, which of course is perfect for restful APIs.
Restful APIs should always be stateless, and the most widely used alternative to authentication with JWTs is to just store the user's log-in state on the server using sessions. But then of course does not follow the principle that says that restful APIs should be stateless and that's why solutions like JWT became popular and effective.
So now let's know how authentication actually works with Json Web Tokens. Assuming we already have a registered user in our database. So the user's client starts by making a post request with the username and the password, the application then checks if the user exists and if the password is correct, then the application will generate a unique Json Web Token for only that user.
The token is created using a secret string that is stored on a server. Next, the server then sends that JWT back to the client which will store it either in a cookie or in local storage.
Just like this, the user is authenticated and basically logged into our application without leaving any state on the server.
So the server does in fact not know which user is actually logged in, but of course, the user knows that he's logged in because he has a valid Json Web Token which is a bit like a passport to access protected parts of the application.
So again, just to make sure you got the idea. A user is logged in as soon as he gets back his unique valid Json Web Token which is not saved anywhere on the server. And so this process is therefore completely stateless.
Then, each time a user wants to access a protected route like his user profile data, for example. He sends his Json Web Token along with a request, so it's a bit like showing his passport to get access to that route.
Once the request hits the server, our app will then verify if the Json Web Token is actually valid and if the user is really who he says he is, well then the requested data will be sent to the client and if not, then there will be an error telling the user that he's not allowed to access that resource.
All this communication must happen over https, so secure encrypted Http in order to prevent that anyone can get access to passwords or Json Web Tokens. Only then we have a really secure system.
So a Json Web Token looks like left part of this screenshot which was taken from the JWT debugger at jwt.io. So essentially, it's an encoding string made up of three parts. The header, the payload and the signature Now the header is just some metadata about the token itself and the payload is the data that we can encode into the token, any data really that we want. So the more data we want to encode here the bigger the JWT. Anyway, these two parts are just plain text that will get encoded, but not encrypted.
So anyone will be able to decode them and to read them, we cannot store any sensitive data in here. But that's not a problem at all because in the third part, so in the signature, is where things really get interesting. The signature is created using the header, the payload, and the secret that is saved on the server.
And this whole process is then called signing the Json Web Token. The signing algorithm takes the header, the payload, and the secret to create a unique signature. So only this data plus the secret can create this signature, all right?
Then together with the header and the payload, these signature forms the JWT,
which then gets sent to the client.
Once the server receives a JWT to grant access to a protected route, it needs to verify it in order to determine if the user really is who he claims to be. In other words, it will verify if no one changed the header and the payload data of the token. So again, this verification step will check if no third party actually altered either the header or the payload of the Json Web Token.
So, how does this verification actually work? Well, it is actually quite straightforward. Once the JWT is received, the verification will take its header and payload, and together with the secret that is still saved on the server, basically create a test signature.
But the original signature that was generated when the JWT was first created is still in the token, right? And that's the key to this verification. Because now all we have to do is to compare the test signature with the original signature.
And if the test signature is the same as the original signature, then it means that the payload and the header have not been modified.
Because if they had been modified, then the test signature would have to be different. Therefore in this case where there has been no alteration of the data, we can then authenticate the user. And of course, if the two signatures
are actually different, well, then it means that someone tampered with the data.
Usually by trying to change the payload. But that third party manipulating the payload does of course not have access to the secret, so they cannot sign the JWT.
So the original signature will never correspond to the manipulated data.
And therefore, the verification will always fail in this case. And that's the key to making this whole system work. It's the magic that makes JWT so simple,
but also extremely powerful.
The contents in a json web token (JWT) are not inherently secure, but there is a built-in feature for verifying token authenticity. A JWT is three hashes separated by periods. The third is the signature. In a public/private key system, the issuer signs the token signature with a private key which can only be verified by its corresponding public key.
It is important to understand the distinction between issuer and verifier. The recipient of the token is responsible for verifying it.
There are two critical steps in using JWT securely in a web application: 1) send them over an encrypted channel, and 2) verify the signature immediately upon receiving it. The asymmetric nature of public key cryptography makes JWT signature verification possible. A public key verifies a JWT was signed by its matching private key. No other combination of keys can do this verification, thus preventing impersonation attempts. Follow these two steps and we can guarantee with mathematical certainty the authenticity of a JWT.
More reading: How does a public key verify a signature?
I would explain this with an example.
Say I borrowed $10 from you, then I gave you an IOU with my signature on it. I will pay you back whenever you or someone else bring this IOU back to me, I will check the signature to make sure that is mine.
I can't make sure you don't show the content of this IOU to anyone or even give it to a third person, all I care is that this IOU is signed by me, when someone shows this IOU to me and ask me to pay it.
The way how JWT works is quite the same, the server can only make sure that the token received was issued by itself.
You need other measures to make it secure, like encryption in transfer with HTTPS, making sure that the local storage storing the token is secured, setting up origins.
Ref - JWT Structure and Security
It is important to note that JWT are used for authorization and not authentication.
So a JWT will be created for you only after you have been authenticated by the server by may be specifying the credentials. Once JWT has been created for all future interactions with server JWT can be used. So JWT tells that server that this user has been authenticated, let him access the particular resource if he has the role.
Information in the payload of the JWT is visible to everyone. There can be a "Man in the Middle" attack and the contents of the JWT can be changed. So we should not pass any sensitive information like passwords in the payload. We can encrypt the payload data if we want to make it more secure. If Payload is tampered with server will recognize it.
So suppose a user has been authenticated and provided with a JWT. Generated JWT has a claim specifying role of Admin. Also the Signature is generated with
This JWT is now tampered with and suppose the
role is changed to Super Admin
Then when the server receives this token it will again generate the signature using the secret key(which only the server has) and the payload. It will not match the signature
in the JWT. So the server will know that the JWT has been tampered with.
Only JWT's privateKey, which is on your server will decrypt the encrypted JWT. Those who know the privateKey will be able to decrypt the encrypted JWT.
Hide the privateKey in a secure location in your server and never tell anyone the privateKey.
I am not a cryptography specialist and hence (I hope) my answer can help somebody who is neither.
There are two possible ways of using cryptography in programming:
Signing / verifying
Encryption / decryption
We use Signing when we want to ensure that data comes from a trusted source.
We use Encryption when we want to protect the data.
Signing / verifying uses asymmetrical algorithms i.e. we sign with one key (private) and the data receiver uses the other (public) key to verify.
A symmetric algorithm uses the same key to encrypt and decrypt data.
The encryption can be done using both symmetric and asymmetric algorithms.
relatively simple article on subject
The above is common knowledge below is my opinion.
When JWT is used for simple client-to-server identification there is no need for signing or asymmetric encryption. JWT can be encrypted with AES which is fast and supersecure. If the server can decrypt it, it means the server is the one who encrypted it.
Summary: non-encrypted JWT is not secure. Symmetric encryption can be used instead of signing in case no third party is involved.
Related
Signing JWT for ADFS to obtain access token
I am new to ADFS, OAuth and JWT and have been looking at this for a number of days; Sorry if silly question or already been answered. I read this guide that deals with authenticating a client using a cert: signing a JWT with a certificate and verifying with the certificate manually uploaded to ADFS: https://learn.microsoft.com/en-gb/archive/blogs/cloudpfe/oauth-2-0-confidential-clients-and-active-directory-federation-services-on-windows-server-2016 It's kind of what I want but not quite - I would like to use certs for user authentication; I would like to sign the JWT with a certificate unique to AD user and be able to have ADFS verify the user in AD as according to the certificate - avoiding the need to manually upload a certificate (plus avoiding the need to upload countless number of user certificates!). Is this possible? The other way of doing it, I was thinking of a JWKS URL with a ton of public certs but that seems mad! (Not sure how I go about producing this endpoint anyway). I appreciate any guidance or pointing me to read articles... Cheers!
This sounds like a feature request to have ADFS support your bespoke idea for signature creation on the ADFS side. To help you understand this in context to how JWT is meant to work: JWT signatures are either: a shared-secret (defined by the JWT producer) for the HMAC-based JWT implementation. JWK (served by JWKS) for the RSA/ECDSA implementation, or; Or concisely: HMAC-based; shared secret, no confidentiality, claims are public RSA/ECDSA; private key generated by the JWT consumer so it can securely decipher (decrypt) claims data that was encrypted by the JWT producer using the public key corresponding to the client private key. Encryption makes claim data confidential. Signatures are therefore (as already described) using public keys (accessed by the client via JWKS URL hosted by the ADFS server) to do the verify method on each end without exposing the private key in more than the location it was intended to be used for decryption purposes. It seems to me you're after a specific HMAC variation based on sharing a Certificate intended as a shared-secret, and that would undoubtedly require ADFS to sign using your shared-secret rather than generate a shared-secret on the server. If you are after a Certificate based Authentication (authentic identity) I would strongly suggest you look at a Certificate authentication scheme rather than try make a modified-JWT scheme to fit your ideas, which it was not designed for. Mostly because you do not control the ADFS source code and can not make it perform non-standard methods or use untrusted (client provided) shared-secret for signature generation when the JWT specification does not support this. (Also you're trying to do Certificate Authentication using JWT that is an Authorization scheme in this ADFS context)
Is it okey to extract userId from JWT token [duplicate]
If I get a JWT and I can decode the payload, how is that secure? Couldn't I just grab the token out of the header, decode and change the user information in the payload, and send it back with the same correct encoded secret? I know they must be secure, but I just would really like to understand the technologies. What am I missing?
JWTs can be either signed, encrypted or both. If a token is signed, but not encrypted, everyone can read its contents, but when you don't know the private key, you can't change it. Otherwise, the receiver will notice that the signature won't match anymore. Answer to your comment: I'm not sure if I understand your comment the right way. Just to be sure: do you know and understand digital signatures? I'll just briefly explain one variant (HMAC, which is symmetrical, but there are many others). Let's assume Alice wants to send a JWT to Bob. They both know some shared secret. Mallory doesn't know that secret, but wants to interfere and change the JWT. To prevent that, Alice calculates Hash(payload + secret) and appends this as signature. When receiving the message, Bob can also calculate Hash(payload + secret) to check whether the signature matches. If however, Mallory changes something in the content, she isn't able to calculate the matching signature (which would be Hash(newContent + secret)). She doesn't know the secret and has no way of finding it out. This means if she changes something, the signature won't match anymore, and Bob will simply not accept the JWT anymore. Let's suppose, I send another person the message {"id":1} and sign it with Hash(content + secret). (+ is just concatenation here). I use the SHA256 Hash function, and the signature I get is: 330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c. Now it's your turn: play the role of Mallory and try to sign the message {"id":2}. You can't because you don't know which secret I used. If I suppose that the recipient knows the secret, he CAN calculate the signature of any message and check if it's correct.
You can go to jwt.io, paste your token and read the contents. This is jarring for a lot of people initially. The short answer is that JWT doesn't concern itself with encryption. It cares about validation. That is to say, it can always get the answer for "Have the contents of this token been manipulated"? This means user manipulation of the JWT token is futile because the server will know and disregard the token. The server adds a signature based on the payload when issuing a token to the client. Later on it verifies the payload and matching signature. The logical question is what is the motivation for not concerning itself with encrypted contents? The simplest reason is because it assumes this is a solved problem for the most part. If dealing with a client like the web browser for example, you can store the JWT tokens in a cookie that is secure (is not transmitted via HTTP, only via HTTPS) and httpOnly (can't be read by Javascript) and talks to the server over an encrypted channel (HTTPS). Once you know you have a secure channel between the server and client you can securely exchange JWT or whatever else you want. This keeps thing simple. A simple implementation makes adoption easier but it also lets each layer do what it does best (let HTTPS handle encryption). JWT isn't meant to store sensitive data. Once the server receives the JWT token and validates it, it is free to lookup the user ID in its own database for additional information for that user (like permissions, postal address, etc). This keeps JWT small in size and avoids inadvertent information leakage because everyone knows not to keep sensitive data in JWT. It's not too different from how cookies themselves work. Cookies often contain unencrypted payloads. If you are using HTTPS then everything is good. If you aren't then it's advisable to encrypt sensitive cookies themselves. Not doing so will mean that a man-in-the-middle attack is possible--a proxy server or ISP reads the cookies and then replays them later on pretending to be you. For similar reasons, JWT should always be exchanged over a secure layer like HTTPS.
Let's discuss from the very beginning: JWT is a very modern, simple and secure approach which extends for Json Web Tokens. Json Web Tokens are a stateless solution for authentication. So there is no need to store any session state on the server, which of course is perfect for restful APIs. Restful APIs should always be stateless, and the most widely used alternative to authentication with JWTs is to just store the user's log-in state on the server using sessions. But then of course does not follow the principle that says that restful APIs should be stateless and that's why solutions like JWT became popular and effective. So now let's know how authentication actually works with Json Web Tokens. Assuming we already have a registered user in our database. So the user's client starts by making a post request with the username and the password, the application then checks if the user exists and if the password is correct, then the application will generate a unique Json Web Token for only that user. The token is created using a secret string that is stored on a server. Next, the server then sends that JWT back to the client which will store it either in a cookie or in local storage. Just like this, the user is authenticated and basically logged into our application without leaving any state on the server. So the server does in fact not know which user is actually logged in, but of course, the user knows that he's logged in because he has a valid Json Web Token which is a bit like a passport to access protected parts of the application. So again, just to make sure you got the idea. A user is logged in as soon as he gets back his unique valid Json Web Token which is not saved anywhere on the server. And so this process is therefore completely stateless. Then, each time a user wants to access a protected route like his user profile data, for example. He sends his Json Web Token along with a request, so it's a bit like showing his passport to get access to that route. Once the request hits the server, our app will then verify if the Json Web Token is actually valid and if the user is really who he says he is, well then the requested data will be sent to the client and if not, then there will be an error telling the user that he's not allowed to access that resource. All this communication must happen over https, so secure encrypted Http in order to prevent that anyone can get access to passwords or Json Web Tokens. Only then we have a really secure system. So a Json Web Token looks like left part of this screenshot which was taken from the JWT debugger at jwt.io. So essentially, it's an encoding string made up of three parts. The header, the payload and the signature Now the header is just some metadata about the token itself and the payload is the data that we can encode into the token, any data really that we want. So the more data we want to encode here the bigger the JWT. Anyway, these two parts are just plain text that will get encoded, but not encrypted. So anyone will be able to decode them and to read them, we cannot store any sensitive data in here. But that's not a problem at all because in the third part, so in the signature, is where things really get interesting. The signature is created using the header, the payload, and the secret that is saved on the server. And this whole process is then called signing the Json Web Token. The signing algorithm takes the header, the payload, and the secret to create a unique signature. So only this data plus the secret can create this signature, all right? Then together with the header and the payload, these signature forms the JWT, which then gets sent to the client. Once the server receives a JWT to grant access to a protected route, it needs to verify it in order to determine if the user really is who he claims to be. In other words, it will verify if no one changed the header and the payload data of the token. So again, this verification step will check if no third party actually altered either the header or the payload of the Json Web Token. So, how does this verification actually work? Well, it is actually quite straightforward. Once the JWT is received, the verification will take its header and payload, and together with the secret that is still saved on the server, basically create a test signature. But the original signature that was generated when the JWT was first created is still in the token, right? And that's the key to this verification. Because now all we have to do is to compare the test signature with the original signature. And if the test signature is the same as the original signature, then it means that the payload and the header have not been modified. Because if they had been modified, then the test signature would have to be different. Therefore in this case where there has been no alteration of the data, we can then authenticate the user. And of course, if the two signatures are actually different, well, then it means that someone tampered with the data. Usually by trying to change the payload. But that third party manipulating the payload does of course not have access to the secret, so they cannot sign the JWT. So the original signature will never correspond to the manipulated data. And therefore, the verification will always fail in this case. And that's the key to making this whole system work. It's the magic that makes JWT so simple, but also extremely powerful.
The contents in a json web token (JWT) are not inherently secure, but there is a built-in feature for verifying token authenticity. A JWT is three hashes separated by periods. The third is the signature. In a public/private key system, the issuer signs the token signature with a private key which can only be verified by its corresponding public key. It is important to understand the distinction between issuer and verifier. The recipient of the token is responsible for verifying it. There are two critical steps in using JWT securely in a web application: 1) send them over an encrypted channel, and 2) verify the signature immediately upon receiving it. The asymmetric nature of public key cryptography makes JWT signature verification possible. A public key verifies a JWT was signed by its matching private key. No other combination of keys can do this verification, thus preventing impersonation attempts. Follow these two steps and we can guarantee with mathematical certainty the authenticity of a JWT. More reading: How does a public key verify a signature?
I would explain this with an example. Say I borrowed $10 from you, then I gave you an IOU with my signature on it. I will pay you back whenever you or someone else bring this IOU back to me, I will check the signature to make sure that is mine. I can't make sure you don't show the content of this IOU to anyone or even give it to a third person, all I care is that this IOU is signed by me, when someone shows this IOU to me and ask me to pay it. The way how JWT works is quite the same, the server can only make sure that the token received was issued by itself. You need other measures to make it secure, like encryption in transfer with HTTPS, making sure that the local storage storing the token is secured, setting up origins.
Ref - JWT Structure and Security It is important to note that JWT are used for authorization and not authentication. So a JWT will be created for you only after you have been authenticated by the server by may be specifying the credentials. Once JWT has been created for all future interactions with server JWT can be used. So JWT tells that server that this user has been authenticated, let him access the particular resource if he has the role. Information in the payload of the JWT is visible to everyone. There can be a "Man in the Middle" attack and the contents of the JWT can be changed. So we should not pass any sensitive information like passwords in the payload. We can encrypt the payload data if we want to make it more secure. If Payload is tampered with server will recognize it. So suppose a user has been authenticated and provided with a JWT. Generated JWT has a claim specifying role of Admin. Also the Signature is generated with This JWT is now tampered with and suppose the role is changed to Super Admin Then when the server receives this token it will again generate the signature using the secret key(which only the server has) and the payload. It will not match the signature in the JWT. So the server will know that the JWT has been tampered with.
Only JWT's privateKey, which is on your server will decrypt the encrypted JWT. Those who know the privateKey will be able to decrypt the encrypted JWT. Hide the privateKey in a secure location in your server and never tell anyone the privateKey.
I am not a cryptography specialist and hence (I hope) my answer can help somebody who is neither. There are two possible ways of using cryptography in programming: Signing / verifying Encryption / decryption We use Signing when we want to ensure that data comes from a trusted source. We use Encryption when we want to protect the data. Signing / verifying uses asymmetrical algorithms i.e. we sign with one key (private) and the data receiver uses the other (public) key to verify. A symmetric algorithm uses the same key to encrypt and decrypt data. The encryption can be done using both symmetric and asymmetric algorithms. relatively simple article on subject The above is common knowledge below is my opinion. When JWT is used for simple client-to-server identification there is no need for signing or asymmetric encryption. JWT can be encrypted with AES which is fast and supersecure. If the server can decrypt it, it means the server is the one who encrypted it. Summary: non-encrypted JWT is not secure. Symmetric encryption can be used instead of signing in case no third party is involved.
How to sign data in .NET Core 3
Question Is there a way to cryptographically sign data (RSA or anything that is considered to be cryptographically secure) and verify that signature so that the signing is done in one HTTP request to an endpoint and verification is done in another HTTP request with another endpoint? Background I'm trying to implement signed URLs. The idea is to protect files or other resources that are usually served via GET (images, PDFs, etc...) by providing signed URL (URLs with a cryptographically signed payload at the end of the URL) which is then validated when requested. So you might have something like an API returning: { "image": "http://api.example.com?key=..." } where ... is the signed payload (which usually contains the user ID, the expiration time and some kind of identifier for the resource). Then when the browser calls for http://api.example.com?key=..., what's in the ... is verified which then either grants access to the image or not. What have I tried I read about RSACryptoServiceProvider, which seems to automatically generate the private key with which stuff is encrypted, but I've also read that it's not thread safe, therefore registering RSACryptoServiceProvider as a singleton is not an option. I'm guessing registering it as scoped or transient would not work when you want the same private key for two different requests (URL generation and file streaming).
How access token is validated for accessing protected resources in token based mechanism?
I want to do token based mechanism where I would be having either SPA or mobile apps supporting multiple clients. Use case of my web service engine and my application: My web application: Client will do registration of their application either SPA or mobile apps.They will get client id on registration.Only client id as secret key would be compromised in case of SPA or mobile apps hence I am just providing clientid. Web service engine: Support multiple client with managing session of each user after login in to respective application of clients. So let's say there are 2 client who have register their application in to my web application : Client 1 : MyApp1 Client 2 : MyApp2 Now if MyApp1 have 2 users with John and Stephen and if they login in MyApp1 then i want to manage session for those users with token based mechanism. Now if John and Stephen wants to access protected resource then they can access only through valid accesstoken. Same goes for MyApp2. For token based mechanism I have seen lots of question referring to this below article only: http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/ But the only confusion part in above tutorial and in most of the tutorial is after validating user name and password and generating access token. Does above tutorial is storing access token in server side cookie for validating accesstoken when request comes to access protected resource? I am really confused here. I know accesstoken validation happens inside [Authorize attribute] but I am not getting without storing accesstoken how above tutorial is validating accesstoken. My thought is like may be when request comes for accessing protected resources access token is encrypted or decrypted based on machine key attribute in webconfig and this is how access token is validated inside [Authorize] attribute but I am just not sure about this.
You can control what information goes inside a token. Look at the SimpleAuthorizationServerProvider class in the article: var identity = new ClaimsIdentity(context.Options.AuthenticationType); identity.AddClaim(new Claim("sub", context.UserName)); identity.AddClaim(new Claim("role", "user")); Use the Claims to store anything you need regarding to the user, their username or roles and this is what happens in the article you referred to. The token generated already contains that information about the user. This is taken from the article : The second method “GrantResourceOwnerCredentials” is responsible to validate the username and password sent to the authorization server’s token endpoint, so we’ll use the “AuthRepository” class we created earlier and call the method “FindUser” to check if the username and password are valid. If the credentials are valid we’ll create “ClaimsIdentity” class and pass the authentication type to it, in our case “bearer token”, then we’ll add two claims (“sub”,”role”) and those will be included in the signed token. You can add different claims here but the token size will increase for sure. This is why you do not need to store the token anywhere,the token is self contained and everything is stored inside it in an encrypted form. Don't forget that before you add a claim containing the username you have already validated the username and password, so you can guarantee that the token is created correctly for a valid user / password combination. Of course you do not want to store the password inside the token, the whole point of tokens is to avoid doing that. Passing passwords to an API all the time does increase the risk of them being stolen, tokens are much better for this. Finally, the tokens expire after a time you control, usually they are short lived so even if someone does get their hands on one they will not last long. If you take care of how you pass the tokens, meaning in the Authorisation Header over an https call then you are as protected as you can be and the headers will be encrypted. The point here is to never issue calls like this over basic http. The author of the article you referenced is a well respected authority in this particular area and currently a Microsoft MVP and you are basically in good hands. Keep reading his articles, but pay attention to the details. ----------- Clarification related to JWT format -------------- yes the JWT token will contain information related to its issue date and expiry date as well. I have an article of my own on this : https://eidand.com/2015/03/28/authorization-system-with-owin-web-api-json-web-tokens/ Look at the calls which create the token and look at the information returned in the screenshots. In my example the token contains the actual encrypted token, the token type, seconds it expires in, the audience which is the ClientID, when it was issued and when it expires. This is just an example of a token, yours will look probably a bit differently but you get the idea I hope. Use Postman to see what's coming back in the token There are a number of concepts to be understood when it comes to OAuth2, it does require a bit of research and practice. In short, you request a token with A Basic Authorisation Header, you get the token back and it's telling you what type it is, in my case it's Bearer so that's my next Authorisation Header for any call to a protected resource. My suggestion is to start small, one step at a time, use Postman to build your calls and understand what's going on. Once you have that knowledge it's much easier to progress. Took me about 6 weeks to wrap my head around all concepts and get something working first time around, but now it takes a couple hours at most. Good luck
The application does not need to store the access token server side, it will only read the user from the token which is passed along. When the request hits the authentication server, which is attach to the Owin pipeline in the ConfigureOAuth() method, the HTTP header token is decrypted and the user data from the token is sat to the current user of the context.
This is one of the things that bugged me for a long time I'm not sure I understand why did you give an example for 2 applications, but the token mechanism is actually simple, but it's kinda black boxed when you use owin and identity the token is not stored anywhere on the server or the database, authenticating the user on login is done using your logic or usually again black boxed in identity, this involves validating a secured password etc after this the token is generated (usually using identity) or if you did it manually this will involve securing the token with whatever info you want to store in it when the user sends a request next time he should pass the token and you will need to decrypt it and validate what's necessary (like expiration time for example), all of this is done behind the scene usually just a fun note: even if you changed the DB completely the token will still be valid with the user id that doesn't even exist in your new DB! but of course identity automatically invalidates this token when it compares with the securityStamp
Can anybody decode a JSON Web Token (JWT) without a secret key?
I am new to this domain but I was trying to generate a JWT using the JWT nuget package. My understanding is that you supply a secret key to sign the Token but when I got the token I went to JWT website to test it and the website was able to decode it without me supplying the secret key. I thought that you generate the token then you sign it and thus prevent anybody from knowing the content of the token unless they have that secret key. Is this not the case?
JSON Web Tokens are an encoded representation of a data structure. It is not required that this encoded data be encrypted, but it is acceptable to do so. From the definition of Code Signing: Code signing is the process of digitally signing executables and scripts to confirm the software author and guarantee that the code has not been altered or corrupted since it was signed by use of a cryptographic hash. A JWT which has been encrypted will typically have two hash values, the first to decrypt the data, the second to validate the code signing. Decoding a non-encrypted JWT is a standardized process, and can be done even if the code sign isn't verified. However, it is recommended not to use any data in a JWT if the code signing hash does not match, as this indicates the data may have been tampered with. Not all JWT implementations support encryption; notably, there is no encryption support in Microsoft's JWT implementation. https://stackoverflow.com/a/18224381/2495283. Therefore, if you have data which you must ensure remains secret, you should encrypt the data using JWE. The JWT standards documentation shows an example of this process. The data is first encrypted, then the encrypted string and decoding algorithm are sent as the payload of the JWT.