I'm trying to understand token based authentication. I've already created a simple app that demonstrates token authentication using OWIN, and I got it to work. I got it from here:
token-based-authentication
However, I'm still confused how exactly does my web api know that the token is valid. My understanding is that the server does not save anything in the memory (in regards to the token); when it gets the token from the client, it will somehow decrypt it, and figure out if it is valid; basically, everything needed to validate the token is in the token itself? Does it use a key to decrypt?..and if so, if I run my web app in two servers, does that mean both servers will have the exact same key?
The token is encrypted (or signed) using a key that only that server has. If it can decrypt it, then logically, it must have originated from that server, therefore it must be a real, valid token.
To use the token across multiple servers, they will need the same key; otherwise they cannot decrypt it or verify its signature.
If signing is used, a public/private key pair can be used, meaning a token generated on another server can be trusted if its public key is known. You would not need the private key to verify the signature.
The exact mechanism for doing this depends on the technologies in use.
Related
I wanted to use encrypted local PASETO tokens for the Request Object in the OIDC, but it turns out that I need to store the key somewhere to decrypt this request object, and it must be available unencrypted/unhashed as it will need the Request Object to decrypt. So I will have to store it as plain text in a database? Pretty dangerous. So I started to wonder how JWE works, but the documentation from https://datatracker.ietf.org/doc/html/rfc7516#section-5.1 about JWE encryption is quite confusing for me. Does JWE solve this problem of storing a symmetric key in a database as plain text or does it have other ways?
There are a few different solutions here, which solve different problems:
ENCRYPTED JWTs
These can be used when the app wants to prevent information disclosure. They are issued by the Authorization Server, which uses a public key to encrypt them. There is then a burden on the app to maintain a private key to decrypt them. See the Encrypted ID Tokens for some example usage.
REQUEST OBJECTS
These are often used to protect against man in the browser tampering. The app only needs to deal with public keys, which it already has access to, so the solution is easier to manage. Newer standards such as PAR and JARM are used, as in this summary.
JWT INFORMATION DISCLOSURE
If you want to avoid revealing sensitive data in access token JWTs, then the usual technique is to return only opaque access tokens to internet clients. This is easier to manage than encryption. See the Phantom Token Pattern for how this works.
SUMMARY
I would usually avoid introducing key management into apps. Aim to manage this in the Authorization Server instead.
I'm developing an ASP.Net Core web application and will be using Auth0 for user authentication.
I'm having a hard time figuring out if my JSON Web Token Signature Algorithm should be RS256 or HS256.
From the information that I have found, I still can't make heads or tails of it. Any ideas?
Even though both algorithms make use of SHA-256, they are fundamentally different:
RS256 (RSASSA-PKCS1-v1_5 using SHA-256) relies on generating a digital signature with a specific private key.
HS256 (HMAC using SHA-256) relies on a shared secret plus the cryptographic hash function (SHA-256) to generate a message authentication code (MAC).
Validating tokens issued with each of the previous algorithms implies that for RS256 the entity doing the validation knows the public key associated with the private key used for signing, while for HS256 it implies that the entity knows the shared secret.
Choosing between one versus the other is then usually motivated by the characteristics of the applications that will validate the issued tokens.
If you want to validate a token on a browser-based application, the use of HS256 is automatically ruled out because that would imply you would have to include the shared secret in a place anyone would have access, making it completely useless because now anyone with access to the code could issue their own signed tokens.
In conclusion, if token validation is done on a controlled environment (server-side) you may go with HS256 because it's simpler to get started. However, if token validation is done on hostile environment you need to go with an algorithm based on asymmetric cryptography; in this case that would be RS256.
How is using a JSON Web Token more secure than an opaque session token, In both the scenarios the tokens are first sent to the client and then verified on the server when a client requests a protected resource.
There are several reasons people say JWTs are more secure. I’ll list them and also give you reasons why that might not really be the case as it swings both ways.
JWTs can be signed using a secret with secure algorithms like HS256 and RS256. A comprehensive list can be found here. On top of that, you can also encrypt the payload of the JSON Web token. However, session tokens can also be generated securely with a top-notch algorithm and stored in a signed cookie.
JWT can either be stored in a cookie or Web Storage( local/session Storage ). If you are not storing your JWTs in a cookie, then you are not vulnerable to CSRF. And you can decide to send them through the Authorization header for every HTTP request. However, there is still a caveat. Javascript is used to access the JWT from the Web storage, which still leaves you open to other forms of attack such as XSS (Cross-Site Scripting). Worthy of mention is that it is easier to deal with XSS than CSRF.
In a situation where your JWT has been tampered with, you can revoke or blacklist the token. This involves making a call to the DB every time you want to perform this kind of operation which I won’t advise you to do. The preferred option is to use short-lived tokens.
In the case of OAuth, opaque tokens otherwise known as bearer tokens are random strings that will be stored in some kind of hashed storage on the server together with an expiration, the scope requested (e.g. access to friend list) and the user who gave consent. Later, when the API is called, this token is sent and the server lookup on the hash-table, rehydrating the context to make the authorization decision (did it expire? does this token have the right scope associated with the API that wants to be accessed?). The main difference between opaque tokens and signed tokens(e.g JWT) is that JWTs are stateless. They don’t need to be stored on a hash-table.
Conclusion
The libraries used to sign and encrypt your JWTs should be secure to ensure your authentication process is also secure. You should also use cookies as storage mechanism rather than using them for login. You can argue that there are more benefits to using JWTs like they are easier to scale and they can be used in OAuth cases which you can find in this article. At the end of the day, In my opinion it simply falls on the developers’ reasoning/logic to ensure the right steps are followed to make an app secured regardless of what form of token is used for authentication or authorization. Use case is also key in this context!
and thank all of you for viewing this question.
I am not sure to on how do this so i am asking for the community help on this matter.
I read int his post Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant" that sessions are not "completely" advised on the REST convention, and that all authentication should be made using HTTP Basic authentication or Digest.
Ok, so far i get it.
But has far has i know, basic authentication is made on the actual server against a regular non-encrypted text file.
Would it be going against the convention, putting the username/password in the http request parameters, instead of passing them down trough the headers and letting the web server do the authentication?
This way, for every request made, the user/pass parameters would be checked and managed using my own logic. I mean using a database table, that has all the info necessary for the application.
The method I currently use is the first request is for a auth token via a POST method, which contains Headers of Username and Password, these are then verified against my authentication methods. If the credentials are valid, I return a time limited token. All subsequent requests must have the auth token as a header, which is checked and if valid access is allowed. I maintain the list of valid token in code and expire them as required. This is faster than having to validate the username & password on each call and is slightly safer than the username & password being passed in with each call as a token could be stolen, but it is only valid for a small period of time.
All of this this must be run under SSL otherwise the data is not secure and users credentials can be read.
Basic auth is handled by the server however the server chooses to handle it. There certainly doesn't have to be a plaintext file containing usernames and passwords! My current client stores passwords in a 1-way salted hash in their database. On an incoming request, the plaintext password is pulled from the header, salted, hashed, and them compared to the database value.
Putting a password in a request parameter is a really bad idea. What happens when a user copies and pastes a URL to email to their coworker?
I'm implementing a rest api to using the new web api framework. This api will be consumed by other companies so we'll be adding an authentication method.
In relation to authentication, I'm thinking to implement something based on tokens. Something like this
client provide credentials to login method
system authenticate client and send a token
client uses this token on following api calls
I wonder if this schema is useful for my scenario. Operations will be mainly atomic, basically clients will periodically ping this api to get some specific data, so not sure if make sense having a session token (at some point the token should expire and not sure how to manage this).
How would you recommend to implement authentication schema for this scenario?
When you generate a token I would store it in a database with a foreign key back to the authenticated login's primary key. I would also (with the token) store the date and time it was established, and a timeout period (you could set this per token, or store it in a config). Check the token/time everytime the service is pinged by that user, then force them to reauthenticate after that time expires (by checking it against the created date stored with the token).
This would make sure that the login information is only getting transmitted after the token expires, when a new token is generated it would delete the old token record.
Am I understanding your requirements right?
Making a token based authentication scheme like this is not easy.
I don't really have an answer for how you could implement it in a good and secure way. But will offer some thoughts off the top of my head about issues you will have to deal with:
The token generation need to be well randomized and the tokens need to be "sufficiently" (for some definition of sufficient) long in order to prevent someone from simply sending a bunch of different tokens to see if he "gets a hit"
The above issues should not be too difficult to implement. But the more tricky thing to figure out is:
How you can you reliably verify that the token has not been "kidnapped".
If the token is simply some random string, then anyone who happens to "see" it in tranfer (use SSL) will be able to assume the identity of the use for which the token was generated.
The token, when received by your service will let you know that:
Your application issued the token to user/application/entity X
The token is intact (has not been changed)
Any other thing you store with the token (is it expired etc)
But it will not without further effort let you know for sure that it was sent by user/application/entity X. It could be Y who has managed to get hold of the token.
That is the case for many authentication schemes of course, so depending on just how sensitive your data is, and also on what kind of operations can be done via you service, it may not be a huge issue for you.