We have a load balance with multiple servers attached to it.
An initial call to our webapi tier acquires a JWT token that is used in subsequent calls.
The problem is the one JWT acquire from server1 used in server2 and failed authentication.
What are the best practices in a load balance situation ?
If you are using frameworks like Laravel for example the JWT token are stored in the cache system the framework uses. Be sure that both server1 and 2 share the cache storage. hope it helps
Related
I have an API service that is currently secured using JWT. I'm going to replace JWT with Identity Server 4 and secure my API with Identity Server 4. I had a custom way of generating JWT tokens (JWE). How can I replace JWT with Identity Server 4 without the current signed-in users to the site need to re-login?
Specifically, I wanna use the Skoruba Identity Server 4 project template.
In IdentityServer, the access tokens are generated to authenticate users. The Access tokens have very small limited lifetime as per convention. There's a concept of refresh token which has longer lifetime and the same is used with basic auth to get new access token. This prevents the hassle to sign in again and again.
The refresh tokens are built using a hash and are persisted in a table (if configured).
JWE is a very different setup altogether. I had my users logged out even after a new deployment of IdentityServer4 (using of persistent grants is helping to solve this).
I don't think it's not technically possible to transfer sessions from one environment to another. Both use a encryption decryption strategies which are very different from each other.
You can give a try by writing a custom implementation of TokenCreationService
I am looking into using microservice for my application. However the application involves authentication. E.g. there is a service for user to upload their images if they are authenticated. There is also a service for them to write reviews if they are authenticated.
How should i design the microservice to ensure that the user just need to authenticate once to access different services. Should i have a API gateway layer that does the authentication and make this API gateway talk to the different services?
You can do authentication at the gateway layer, if authentication is all you need. If you are interested in authorization, you may have to pass the tokens forward for application to consider it. Also you can do that, if you have trust on other services behind the gateways. That is service 1 is free to call service 2 without authentication.
Also you loose bit of information about the principal, you can however write it back on the request in the gateway while forwarding.
Also another point to consider is JWT, they are lightweight and more importantly could be validated without calling auth server explicitly and it saves you some time specially in microservices. So even if you have to do auth at every service layer you are doing it at minimal cost, some nanoseconds. You can explore that as well.
However final call is based on how strong your security needs are compared to rest. based on that you can take a call. Auth stripping at api gateway saves you code duplication but is less secure as other services can do as they wish.
Same goes for token, you can authenticate without explicit call to auth server but then tokens are valid for some min time and bearer is free to do as they wish once they got the tokens, you cannon invalidate it.
While Anunay's answer is one the most famous solutions, there is another solution I would like to point out. You could use some distributed session management systems to persist sessions on RAM or DISK. As an example, we have authentication module that creates a token and persists it in Redis. While Redis itself can be distributed and it can persist less used data on disk, then it will be a good choice for all microservices to check client tokens with redis.
With this method, there is nothing to do with API gateway. The gateway just passes tokens to microservices. So even in case you are thinking about different authenitcation methods on different services, it will be a good solution. (Although I cant think of a reason for that need right now but I have heard of it)
Inside a session, you can store user Roles and Permissions. That's how you can strict users access to some API's. And for your private API's, you could generate a token with role ADMIN. Then each microservice can call other one with that token so your API's will be safe.
Also you could rapidly invalidate any sessions and store anything you want in those sessions. In our system, spring framework generates a X-AUTH-TOKEN that can be set in headers. The token is pointing to a session key in redis. This works with Cookies too. (and if I'm not wrong, you could even use this method with oAuth and JWT)
In a clean architecture you can create a security module that uses this validation method over API's and add it to every microservice that you want to protect.
There are other options when it comes to session persisting too. Database, LDAP, Redis, Hazelcast ... the choice depends on your need.
I am in the process of setting up a central JWT authentication / authorization service. We will have multiple APIs that a client will need to communicate to and be authenticated against.
My thought was to have the user login, which would authenticate against the JWT server. It then uses that token to communicate with the other resource APIs. Those APIs would validate the token against the JWT server before sending the request back.
Is this a pretty decent approach to the problem? Has anyone implemented something like this? One issue I see right away is there is a lot of communication to the JWT server.
This sounds like a decent approach. I have implemented a solution where the JWT service was a part of my API. As i understand from your question, you want to have this JWT service separately so that a user can interact with different services/application using the same token. This is called Single Sign On.
If you think your JWT service is getting a lot of traffic, you can always spin up more instances to handle the additional load.
As long as your service is just getting token from a database and responding to request quickly and not doing any calculations, i do not see it getting affected by a lot of traffic.
Well i have a scenario where i have a rest api built on laravel and controlled by JWT. Then i use another route to request the api for the token. But once i receive the token after giving the login credentials where should i save the token?
I think it should be saved in the client's browser, so on the next request we just fetch the token from the browser and then go through another request. Saving the token in the browser will also give the advantage with scaling the server, because if its on the server's session not all the servers will be in sync with this session data.
Now i want your opinion on this, should i store the token in a cookie or in the browser's LocalStorage? I know how to store it in cookie but dont know how to store in localstorage with js. It would be helpful if you could point out to any tutorial for this.
There is a good article here on local storage vs cookies with JWT. They recommend cookies because of XSS vulnerabilities when using local storage.
It is also worth pointing out that if you are using the Laravel JWT Auth package, that the token is still being stored on the server (using Laravel's cache system) by default, and so will not scale across servers. You should be able to change this with the storage config option.
I'm building a picture diary on web application google app engine using python. Users can sign up and post pictures to their diary.
Also, I'm trying to conform as much as I can to the REST architecture of doing things.
The authentication scheme is based like this for the web application:
1. Post username/password from the frontend
2. Backend sets up a cookie if authentication is successful
3. The rest of the AJAX calls made are authenticated using this cookie.
Is there any way to conform to REST without using cookies ?
Now, I'm also building an android application where users can sign in and post/view their picture diary. I need to expose the data from web application's datastore so I'll be building a webservice to fetch data from the datastore.
The authentication scheme for the android client:
OPTION a
1. Post username/password over https to the web service
2. Web service returns a unique authorization token (store the token in the username/pwd table on the datastore)
3. Request subsequent services by adding this token to the Request Header of the request
4. Server maps the token to the username/pwd table and returns data if token is found
5. Authorization token expires after a certain period of time
OPTION b
1. Set up a secret key on the client and server side
2. Use "username:hash of password and secret key" in the authorization header of every request
3. server generates the password by extracting the password from the hash value using the same hash algorithm ; if successful returns data
btw, I didn't wanna use basic authorization because of its security vulnerabilities.
Which is better ?
Are there other significantly better ways to accomplish what I'm trying to do ? Security is quite a concern for me btw.
I'd appreciate if anyone has any insight into this issue. thanks.
I've been doing some research myself as to what would be the best solution. I think the 2-legged oauth might work in my case as Leonm suggested.
In this case the server has to provide the client with a consumer key/secret which in my case is hardcoded in the app.
The steps now would be:
1. Generate a signature using the oauth_parameters(consumer_key, signature_method, timestamp), request url, request parameters, and the SECRET.
2. Include the signature, oauth parameters when making a request.
3. Server verifies the request by generating the signature again except in this case it uses the SECRET that corresponds to the key
I think this way I am pretty much confirming to the REST principles. The server is statless as I far I understand now.
What are the pros/cons on doing things this way?
If "security is a concern" then I would say that you'd be a lot better off using open standards and a library to achieve what you want. The main reason for this is that if you do it yourself, you're very likely to forget something; these standards have had a lot of eyes looking at them, looking for holes.
Your options include (in increasing level of complexity)
Basic authentication and HTTPS
Everything is encrypted, which makes it impossible to compress or look into, it increases the overhead somewhat, using more horsepower on the server, and more perhaps battery power on the client. Simple to implement, since it's well supported by libraries.
Digest authentication
Unencrypted messages pass the wire, but the authentication is securely managed in the Authorization headers. See the wikipedia entry for more information.
OAuth
See how Google is providing OAuth for installed applications. I believe it isn't what you're looking for, since you're not asking to share data between applications, just authenticating users.
Roll your own
If you want to roll your own, I suggest looking at e.g. how Google's (now deprecated ?) ClientLogin used to work.
Clients would GET a protected resource, and get a 401 with instructions to perform a GoogleLogin authentication, including a URI for where to perform the login itself
Clients (knowing how to do this) POST a request in a specific manner to that URI
The server responds with a specific response including a (long) token
The client can now perform GET requests to the protected resource with that token.
Statelessness
You cite REST, which dictates that requests should not specifically depend on prior interaction: "... 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." (fielding) This means that a server shouldn't store conversational context (like an authentication token) in a table.
One way of fixing this is by using any of the token based approaches (where the server tells the client about a token it should use for future requests) where the token is not a random number, but a message to the server itself. To protect yourself from client tampering, it can be signed, and if you're afraid of clients looking at it, you can encrypt it.
Edit: Although I'm not certain, it seems unlikely that Google has a table of all authentication tokens ever issued; The length of their tokens suggests that the token is some encrypted message proving that whoever holds this token actually provided real credentials in some realm at some time.
OAuth does exactly what you want to do in a standard way.
You could use a combination of HTTPS and HTTP Basic Auth. Both are existing standards and should be secure enough when used together.