for example: if i have Asp.net web Api Application and this application get a Token from Client To send Notification for this Client with this Token and every Client have a different Token.
How can I save this Token for each individual Client To every Client use his Special Token more Times from different Computer or From different Browser??
Schould I use cookies or Session or is there something else??
It is worth noting that the Token is sent from the client and used by the server
The WebAPi is a Stateless Project that mean you do not need to manage the state for every client!
For example, if you use JWT token, once the token created by API, client must send the token for every request.
BUT
If you need to save a token for more use!
Four options come to mind :
1-use your primary db(ex:SQL Server) to save the token!and retrieve every time you need!(Not a good idea)
2-save your token to Redis!
3-create a static class with Singleton lifetime, then with dictionary you can save the token for every client to memory!
4-Use In-memory Database link
Related
I am implementing a Spring Boot application, in which the methods are calling third party REST endpoints. This REST API is accessible after OAuth2 authentication. That is why I retrieve tokens from the third party (various users can use my application and respectfully call the REST endpoints) and use these tokens for authorization in order to call the endpoints. But in the current implementation this happens before every call. That is why I would like to ask for advice how to cache these tokens and whether this is a good practice at all? Also the tokens expire in 1 hour.
You should not cache access tokens on the backend of a web application ,if you can store them client side and send them with each request.
In case you don't have possibility to store it at client side (possible case your API is talking to some message client like USSD,SMS etc),It will be expensive to get an OAuth access token, because it requires an HTTP request to the token endpoint. This case is a good example where you can cache tokens whenever possible.
You can make use of REDIS if you have multiple instances.
REMEMBER : Tokens are sensitive data, because they grant access to a user's resources. (Moreover, unlike a user's password, you can't just store a hash of the token.) Therefore, it's critical to protect tokens from being compromised. You can make use of encryption.Do check below links for more details :
https://auth0.com/docs/best-practices/token-best-practices.
https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md#5-obtaining-and-storing-access-tokens-to-call-external-apis
https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/token-cache
As per Auth0 Token Best Practices
Store and reuse.
Reduce unnecessary roundtrips that extend your application's attack surface, and optimize plan token limits (where applicable) by storing access tokens obtained from the authorization server. Rather than requesting a new token, use the stored token during future calls until it expires. How you store tokens will depend on the characteristics of your application: typical solutions include databases (for apps that need to perform API calls regardless of the presence of a session) and HTTP sessions (for apps that have an activity window limited to an interactive session). For an example of server-side storage and token reuse, see Obtaining and Storing Access Tokens to Call External APIs in our Github repo
I am working on a nodejs project and coming from a PHP background. I am pretty impressed with frontend and backend development separately and communicating with API calls.
# Issue: I need to authenticate the user and store some data of the user (which is always needed in the server), this user data which results in increased jwt payload size and jwt token will be large.
So I used JWT token mechanism, generated a token after successful login and send it to the client, then the client add that token as the header with every API call - then verifies token in server and gets the decoded payload data.
This is the process. But I have some user data that is needed always in nodejs, so the JWT payload size increases and JWT token size also large size. So client always sends with large size token everytime.
I was using sessions in php to maintain user data.
If I use sessions for authentication, it will be stateful, right?
# Doubts:
Is there any way to maintain the logged in user data in the server?
How to reduce the length of JWT token if I use large payload?
Updated:
Also if I am using sessions, it makes use of the database to store sessions So a DB call is needed.
What if I use small payload token (eg: userid) for authentication and after authentication make a DB call with userid to get details?
In both methods DB call is needed? Which method seems better?
Using sessions would introduce server state, but lets you keep user data and session data on the server. Only the session id has to be shared with the client.
You cannot reduce the length of the JWT token. Larger payload means a larger token. In theory you could use some kind of compression, but that would be a very high technical overhead and probably not worth it.
Saving sessions on the server would solve your problems.
It also gives the server complete control over the sessions. When the user logs out, the server can delete the session. When the client deletes his JWT token, you cannot be absolutely sure that the user is logged out. The token itself is still valid.
Using JWT as a sessions container is generally a bad idea. This just introduces several security issues, that you have to handle yourself. You have to make sure that 3rd party JavaScript does not read the token, just to name one issue. There are many blog posts, which explain these issues in detail (search for "Stop using JWT for sessions"), but I can only advise not to use JWT for sessions. Sessions are not a bad thing!
I have two Spring Boot REST applications. One of the applications calls other with Spring RestTemplate. Lets call these applications server and client app.
Server app is sending XSRF-TOKEN token as cookie, this is done for the UI part. However there's no way (None that I know of) for the server to distinguish between the request coming from browser and a request coming from the client app. So I can not selectively send the CSRF token from the server to browser only.
Is there a built in mechanism in Spring which allows RestTemplate to detect CSRF cookie/header and replay the request?
If not how can I do the same manually? Should I wait for the CSRF exception to occur and then read the cookie fro the response and replay it?
If it were to be done once then it would be OK, however to wait for the exception for every RestTemplate call doesn't seem right.
I may try to store the token once and set in from the next time, however how would it deal with the multiple server app scenario (Which I have to implement next). As CSRF token of one server app would be invalid for the other, so I won't be able to store a single token, but I would have to store a map of tokens which would have an entry for every new server app URL.
This all seems too complicated, I would rather have Spring handle it.
Any clues are appreciated.
Thanks
For now I have implemented a REST service without protection in the server app which can be called to get CSRF cookies. I had to allow session to be created always so that CSRF cookie doesn't change in one session and so that I could avoid the error Could not verify the provided CSRF token because your session was not found.
Client app calls CSRF rest service to get the cookies and then sends it with the next service call.
It seems a much to call the CSRF token service for each REST call via RestTemplate however it saves me from implementing complicated logic of storing the session. CSRF token service just delivers the cookies so it's network call doesn't take much time compared to the actual service call.
I was also thinking of using a persistent storage (SQL Database or Redis) to store the CSRF token for the server app and then let the client app directly read it from the persistent storage.
However I couldn't figure out how to associate the Session + Server app + CSRF token together to identify token needed by client. As client doesn't have the session initially, so it can't uniquely find CSRF token for it's token from the database. This method is complicated further by the fact that RestTemplate doesn't store the session for the next call.
I trying to implement a token based authentication approach:
Every successful login creates new token.
If user selects "keep me logged in" or the user is using a mobile device, the token is persisted in a Redis database without an expiration date. Otherwise, the token will expire in 20 minutes.
Once user is authenticated, the token is checked from each subsequent request in my Redis database.
I'm wondering how I can identify devices. In case of mobile devices, I can use a device identifier. But how can I identify a browser?
Example: The user logs in using Chrome and selects "keep me logged in". A token is generated and persisted with the browser name in Redis. If the user logs in from Firefox, saves the token and "Firefox" in the database. I save the token in Redis whereas token is created on successful authentication. Is it fine to persist only the token and the browser where the token is being used? Or do I need to persist the IP as well?
Additional question: How to avoid attackers to steal the token from a cookie?
How token-based authentication works
In a few words, an authentication scheme based on tokens follow these steps:
The client sends their credentials (username and password) to the server.
The server authenticates the credentials and generates a token.
The server stores the previously generated token in some storage along with the user identifier and an expiration date.
The server sends the generated token to the client.
In every request, the client sends the token to the server.
The server, in each request, extracts the token from the incoming request. With the token, the server looks up the user details to perform authentication and authorization.
If the token is valid, the server accepts the request.
If the token is invalid, the server refuses the request.
The server can provide an endpoint to refresh tokens.
How to send credentials to the server
In a REST applications, each request from client to server must contain all the necessary information to be understood by the server. With it, you are not depending on any session context stored on the server and you do not break the stateless constraint of the REST architecture defined by Roy T. Fielding in his dissertation:
5.1.3 Stateless
[...] each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. [...]
When accessing protected resources that require authentication, each request must contain all necessary data to be properly authenticated/authorized. It means the authentication will be performed for each request.
Have a look at this quote from the RFC 7235 regarding considerations for new authentication schemes:
5.1.2. Considerations for New Authentication Schemes
There are certain aspects of the HTTP Authentication Framework that
put constraints on how new authentication schemes can work:
HTTP authentication is presumed to be stateless: all of the
information necessary to authenticate a request MUST be provided
in the request, rather than be dependent on the server remembering
prior requests. [...]
And authentication data (credentials) should belong to the standard HTTP Authorization header. From the RFC 7235:
4.2. Authorization
The Authorization header field allows a user agent to authenticate
itself with an origin server -- usually, but not necessarily, after
receiving a 401 (Unauthorized) response. Its value consists of
credentials containing the authentication information of the user
agent for the realm of the resource being requested.
Authorization = credentials
[...]
Please note that the name of this HTTP header is unfortunate because it carries authentication data instead of authorization. Anyways, this is the standard header for sending credentials.
When performing a token based authentication, tokens are your credentials. In this approach, your hard credentials (username and password) are exchanged for a token that is sent in each request.
What a token looks like
An authentication token is a piece of data generated by the server which identifies a user. Basically, tokens can be opaque (which reveals no details other than the value itself, like a random string) or can be self-contained (like JSON Web Token):
Random string: A token can be issued by generating a random string and persisting it to a database with an expiration date and with a user identifier associated to it.
JSON Web Token (JWT): Defined by the RFC 7519, it's a standard method for representing claims securely between two parties. JWT is a self-contained token and enables you to store a user identifier, an expiration date and whatever you want (but don't store passwords) in a payload, which is a JSON encoded as Base64. The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server. You won't need to persist JWT tokens if you don't need to track them. Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To keep the track of JWT tokens, instead of persisting the whole token, you could persist the token identifier (the jti claim) and some metadata (the user you issued the token for, the expiration date, etc) if you need. To find some great resources to work with JWT, have a look at http://jwt.io.
Tip: Always consider removing old tokens in order to prevent your database from growing indefinitely.
How to accept a token
You should never accept expired tokens or tokens which were not issued by your application. If you are using JWT, you must check the token signature.
Please note, once you issue a token and give it to your client, you have no control over what the client will do with the token. No control. Seriously.
It's a common practice to check the User-Agent header field to tell which browser is being used to access your API. However, it's worth mention that HTTP headers can be easily spoofed and you should never trust your client. Browsers don't have unique identifier, but you can get a good level of fingerprinting if you want.
I don't know about your security requirements, but you always can try the following in your server to enhance the security of your API:
Check which browser the user was using when the token was issued. If the browser is different in the following requests, just refuse the token.
Get the client remote address (that is, the client IP address) when the token was issued and use a third party API to lookup the client location. If the following requests comes an address from other country, for example, refuse the token. To lookup the location by IP address, you can try free APIs such as MaxMind GeoLite2 or IPInfoDB. Mind that hitting a third party API for each request your API receives is not a good idea and can cause a severe damage to the performance. But you can minimize the impact with a cache, by storing the client remote address and its location. There are a few cache engines available nowadays. To mention a few: Guava, Infinispan, Ehcache and Spring.
When sending sensitive data over the wire, your best friend is HTTPS and it protects your application against the man-in-the-middle attack.
By the way, have I mentioned you should never trust your client?
Once server is receives the request from the client, it contains the User-Agent. This attribute will help us to identify the client.
Please refer this link: How do I detect what browser is used to access my site?
It has been a long road but I have SignalR working with my Web API which uses OWIN for token authentication.
I have a mechanism where if a user authenticates on terminal #1 and then later authenticates on terminal #2, I can send them a Javascript alert saying "Hey, only one session at a time. Which one do you want to log out?"
The question I have is how to kill their "session" on one of the terminals? I say "session", but since this is a REST based API there really is no session. If I could force them to re-authenticate on the terminal they choose to "log out" from that would be sufficient.
I have the SignalR connectionId of each client. Is there a way I can expire their authentication token and force a logout?
Note - The client is separate from the Web API in that they are hosted on two different servers. The client is just HTML/Javascript making calls to the Web API.
If you are using a bearer token approach, and you are not storing tokens (or token hashes) into some kind of persistent storage (e.g. a DB), then you have no way to invalidate a token.
Since OAuth is not an Authentication protocol, it do not have any kind of log out concept in it. Your only option is to remove the token from the client storage (I can imagine it is stored inside the localStorage or in a cookie).
Of course this does not really invalidate anything, and if the token is not deleted for some reason, it can still be used for authorization purposes.
Your only option, if you really need a single access token valid at a single time, is to store some information about it in a database, and check that storage every time you validate the token. You could, for instance, store the hash of the token (never store the real token for this reason, they have the same value of passwords once stored) with the username, but please note that this approach makes your authorization protocol a little less stateless than before.