I'm a new to microservice architecture. In general, we have an applictaion broken into microsrvices. I was advised to use API Gateway as a client request router. I chose the Express-Gateway. And that's what i want to do: I need that when unauthorized user sends a request, his request would be redirected to the authorization service. On the authorization service the SMS code would be validated and then a JWT would be generated. This token would be sent to the client and saved in the Express-Gateway system. In the future, Express-Gateway would check the token and, upon successful validation, redirect requests to other services. How can I implement such a solution, or are there other options? I just don't like Express-Gateway's Consumers Management System, and I need my own authentication logic.
Related
I am looking for advice on data sharing between microservices.
My app has 3 services but in this case, I need to share data between only 2 services:
-Main (Handling requests, store user data)
-Upload (Receive files and modify)
Before the user can send a file to the server, the server must verify if that the user exists and whether he has permission to send files.
My idea for it is to create a private API in the main service with an Nginx API gateway, so the upload service can make HTTP requests and fetch data about the user and permission. Does it make sense? or there is an easier solution for it? I use express and postgresql.
It is a good approach, but perhaps, the main service should be the auth server.
I mean, in order to ensure that a user has the proper permissions to do an action you have to use something to identify the user and something that cannot be altered, this normally is achieved using a signed token.
This token is created by the auth server when the users log into the application and when it is passed to a service, this service can check against the auth server if the token is valid and if the user identified by the token has the correct permissions to execute the action.
This process is very similar to the one you have explained before. In your case, the user service will be the auth server that is responsible for the authentication and authorization of users and the upload service is the one that is consumed
As you have two microservices(Customer, File upload).
The best way to communicate to other microservices is through the HTTP call(GET,POST,DELETE,PATCH) exposed by that MS.
In your case Customer microservices has few endpoints like GetCustomer,CreateCustomer,DeleteCustomer,PatchCustomer. Before uploading the file you can call the GetCustomer API for checking the customer's existence in the system. If it is present, then proceed with further processing of file data.
As mentioned by JArgente, Use the authorization token for authentication and authorization of microservice endpoint. Pass that token in HTTP_Header while calling the Microservice and validate that against your Authorization server. You can write the interceptor, which validates the token.
As long as your main server can authenticate the user, and verify the user is authenticated, you can implement a JWT token.
If your client is already sending a JWT token to your main server, the same token can be used to communicate with other microservice.
If not you can always generate a new JWT token to be sent to your micro services, without maintaining any centralize database
var token = jwt.sign({ user: 123 }, privateKey, { algorithm: 'RS256'});
My client application is a SPA built with REACT-REDUX and back-end API is nodejs with express framework.
Problem is in my client application people can access information without login
so how to authenticate my client application without actually login to my server API.
I tried to use Auth0 but for Single page web application authentication is done only through login, there is an option for machine to machine but that is not suitable to my case because my client app is static web app no server to save client id.
i have studied few articles to get over from this most of them suggest implicit grant is suitable for my case if its true how to implement implicit grant in my client and server.
I have achieved this using JWT
Provide the client a JWT token on successful login which he will have to use in header every time he needs to use API.
then every other request use a middle-ware to verify this token, if valid let him continue or else send auth failed in response
I am wanting to build a authentication/authorization service using NodeJS, Mongo, and JWT. This service would be a micro-service that handles requests not only from my API Gateway before allowing requests, but from other services that might want to check auth and roles. I am assuming that all other services will use this Auth Service to validate the JWT as well as roles, etc.
Hopefully this diagram better explains what I am looking for.
Can anyone point me to a resource that might help me learn how to do this with NodeJS?
If you have a single client application then you can do following steps
Make one microservice for authentication that generates jwt token.
The jwt contains all essential user information in its payload, ie Role, UserId etc.
The jwt token will be sent in Authorization header for every authorised request.
Before processing any request you can validate and decode the jwt token using middlewares. Now you can set the user's info in req object easliy and can easily access users role and its id in your controller.
if the token is not valid then you can throw error in middlewares and it will provide json response of unauthorised.
You can call the authentication api to validate and decode your token or you can write 3 to 4 line of code in every microservice in middleware.
Here are some links for sample implementation of jwt, you should customize these sample code according to above steps.
5-steps-to-authenticating-node-js
authenticate a nodejs api with json web tokens
If you have multiple client applications
You should use openid connect standard that provides single sign on solution to authenticate multiple application with same username and password.
here is a openid connect playground to understand the authorization flow.
I'm writting a toy application for practicing microservices and authentication on nodejs (expressjs).
I have a react client, an authentication service and other services (they just respond "Hi" so far).
The client will be hosted in a CDN.
The auth service listens on port 5000 (for example)
The rest of the services listen on port 6000-6100.
I have a redis db to store session information (oauth token provided by twitter).
A mongodb where the application information is stored (not relevant for this question).
The idea is that an unauthenticated client goes to the auth service by clicking the Twitter button (SSO). Then the auth service obtains the generated twitter oath token and it sets this token in the redis store. Then the token is accessible to the rest of the services so they know if a request is authenticated or not by checking if the it already exists in the redis store (if the user removes its account, it will also be deleted from the redis store).
I send the twitter token back and forth from client to server once authenticated.
I find this approach pretty simple (others use an nginx proxy for authentication but I see no reason for that, except if the services are hosted in different domains, but I don't understand it very well) so I'm worried I'm missing something about security for example.
Questions:
Is this approach correct?
Is it safe to share the twitter token (I think so)?
Is there any security issue I'm not noticing here?
Using this approach you will have to validate the token in all your services, if you are okay with this then you are probably fine.
The twitter access token may have an expire time that will make it necessary to use a refresh token to get a new access token from the auth service:
When the access token expires you would return a 401 to the client, from the Service X that you are trying to talk to.
The client would have to call the Auth service providing a refresh token, getting a new access token
Finaly the client would be hitting the Service X again with this new access token, have it validated and get the expected response from Service X.
In my recent assignment I wrote a micro-service that proxied all the tokens, using this approach my proxy handled everything from auth to roles and sending 401's for expired tokens and revoking refresh tokens etc. I think this gave me a greater separation of concerns.
Important Note: In the refresh token scenario above my proxy only would experience load for an invalid/expired accesstoken, whilst in your scenario any service could be reached with invalid tokens...
Another approach would be to let Service-A and Service-B call the auth service to validate the tokens, but this would infer a lot of more traffic between the services since each HTTP request with a token has to be validated. In this scenario as well a invalid token request would reach your Service X and hence infer some load on it...
I have an OAuth secured REST service "Oservice". The client (who wants to access OService) is not able to request a token at the service's token generator. I would like the WSO2 ESB to handle this for the client:
1) The ESB should have an API, which receives the request from the client, adds the name + password and sends this request to the token generator.
2) The ESB should receive the token and add the token to the message from the client and forwards it to the Oservice.
3) The Oservice receives message from ESB, validates the token and replies with correct content to ESB and ESB will forward the reply to the client.
I was trying to find out whether OAuth mediator does this, but wasn't successful, since documentation is rather short for the OAuth mediator.
Does anyone have an idea how to deal with this scenario?
Thanks a lot!
EDIT:
The goal is to use the ESB to expose a secured service as not secured to clients. I hope this clarifies a bit.
OAuth mediator can only be used to validate the OAuth access token which comes with the request. In your use case the back-end REST service is secured with OAuth and the request which comes via the ESB should have the access token. In this case OAuth mediator is of no use since token validation happens at the backend, not at ESB. This article explains how OAuth works. In step 2 and 3 you will anyway need human intervention to authenticate the resource owner which is not designed to be done programmatically. So your complete requirement does not seem to be valid because the final resource is accessed by the application, not the resource owner.
However I think some part of your requirement can be fulfilled. Say you have two REST APIs API1 and API2 in ESB.
Client sends a request to API1 just to trigger the API.
API1 sends a request to IDP with Client ID, scope of authorization and callback URL which is URL of API2.
IDP will redirect the client to the authentication page where he will authenticate himself. At this point clients HTTP request is fulfilled.
IDP will send the Authorization code to API2.
API2 will use the Authorization code and client secrete to get the Access token from IDP.
Once the Access token is received, API2 can access your Oservice and get the response/resource.
API2 will have to store the response somewhere like a file.
The client can make another request to say API3 to retrieve it.
Hope this helps
In your case you may use OAuth2 resource owner credentials grant type which is used when there is a high trust with the application using the resource owner credentials.
Now you may expose the IDP OAuthService (which is a SOAP service) as REST say API1 at ESB.
IDP OAuth service takes input as client id,client secret, resource owner username, resource owner password and grant type (=password) and returns access token with validity period.
Now you may call API1 to get the access token and then use that token while calling other OAuth protected APIs.
Hope it helps.