How to pass JWT token from a microservice that consumes another microservice? - spring-boot

I have two microservices say A and B. In all REST endpoints for both microservices, I have implemented JWT authentication. A user has to hit an endpoint ("/login") with username and password and generate a token and pass this as a RequestHeader to all end points in both the services.
Say in microservice A, I have an endpoint ("test1/createSomething"). In B I have another have an endpoint ("test2/getSomething"). Now I am able to call ("test2/getSomething") from service B, in ("test1/createSomething") in service A using Feign client.
But I am not sure how to implement this in a way that I generate the JWT token in service A and pass it along to service B, to consume its services.
Please help. Beginner in microservices and exploring things.

One approach you can try is by having a separate session/jwt service.
Roles and responsibility of that service would be to store/validate and authenticate having following endpoints.
create_token() : create new JWT token with given input data(say user info, expiration time etc)
is_token_valid() : check if token is valid or not
So you can have a flow like this :-
1. First hit to login-service > login service getting token from jwt-service > returning jwt token to UI/client.
2. UI/Client passing received jwt token to service-b via headers> which indeed pass jwt token to service-a, where each service independently calls is_token_valid() of jwt-service and process the request only after getting success response.
To implement this in spring-boot, what you can do is by adding an interceptor layer, that is being called before every Controller class, where is reads headers, extracts jwt-token and validates that from jwt-service.
You can look at the similar answer here.
Another reference here

Related

Block jwt of a banned user in spring cloud gateway filter

i am creating a spring microservices project. my project is composed of eureka, spring cloud gateway and other microservices.
what i am doing is validating user jwt in spring cloud gateway, but validating the token only is not enough, i also want to check if user state is valid or not, for example I want the gateway to return to the client "UNAUTHORIZED" if his account is banned.
what i'm doing now is letting the user use his token until it is expired, but once the token is expired and the user tries to renew it, i inform him that he's banned and he can not get a new jwt.
what i want to do is block him even if his token is not expired yet, i don't want him to access endpoints once his account is suspended.
I know that I can call the user microservice in the gateway filter to obtain his state .. but I don't want to do this on every api call, because i think that's a little more expensive.
Are there solutions to manage this situation?

Access spring security principal in microservies ,when actual authentication has done in ZUUL gateway

In our project JWT token validation and other authorization related logics are done in ZUUL gateway. If zuul succesfully validated the token it will proceed the request to the corresponding microservice
In that case, How can i send Principal to other microservices, when JWT authorization has been done from ZUUl gateway .
I can of course fetch the token using #RequestHeader(value="Authorization")in controllers of other services.
But in order to use #Preauthorize(id,principal) kind offunctionality, i need principal in other microservices where the actual authentication has not been taken place.
is it possible to do this?
Yeah it's possible.
Whenever creating or generating new Jwt token add your ( user details or any useful information that need to be consumed in downstream microservices ) in the Jwt token claims.
Whenever routing happens in Zuul API gateway it will pass the current request to your downstream microservices. In that incoming request you can get your Jwt token from the request header.
Steps to access the User details or any information using Jwt token from any microservice :
Get the token from the request header.
Parse the token with correct signing key and get the user details from the token claims.
For your reference : https://medium.com/#Baimurzin/how-to-get-the-current-user-in-spring-cloud-microservices-c876e1c6fc65

Authentication and authorization as a central MicroService ASP.NET

I am planning to change the ASP.NET Web API 2.0 which includes Authentication and Authorization and all the services into Microservices architecture.
My Question if I create a central microservice to handle authentication and authorization. How do I authorize the users sending the request with their tokens to other services?
To elaborate the question:
Let'say I have three microservices.
1 ) ASP NET framework handling authentication and authorization, Which will authenticate a user and sends a token.
2 ) Orders service, Which will receive the requests with the token in their headers. (ASP NET core)
3 ) Accounting service, which will receive the requests with the token in their headers. (ASP NET core)
How do we authorize the users when they call service 2 or 3?
And Is this an ideal approach?
Instead of authenticating external requests at each microservice (you may want to do that for internal microservice communications), I would install a gateway (for example Ocelot which can handle the external "upstream" authentication for you using whatever system you're using, for example for Jwt bearer:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication()
.AddJwtBearer("TestScheme", x => ...
}
Then in Ocelot you can decide which routes require this scheme as follows
"Routes": [{
"DownstreamHostAndPorts": [...],
"DownstreamPathTemplate": "/",
"UpstreamPathTemplate": "/",
"AuthenticationOptions": {
"AuthenticationProviderKey": "TestScheme", //<--here decide to use this scheme
"AllowedScopes": []
}
}]
If Authentication is successful you can use Ocelot's method of "claims to claims transformation" from your upstream to downstream this method - I personally wanted customise this and build a new Jwt token for internal authentication so used my own downstream handler, like this:
services
.AddHttpClient<IMyService, MyService>(client => ...)
.AddHttpMessageHandler<MyJwtDownstreamHandler>();
//then in the MyJwtDownstreamHandler
request.Headers.Authorization = new AuthenticationHeaderValue(
"bearer",
TokenGenerator.Generate( //<--generate your own Symmetric token using your own method
identity: myIdentity, //<--claims for downstream here
)
);
Based on comments Above
External Identity provider
You may need to use external identity provider e.g. identiyserver4 , azure ad or auth0 etc. Since the token may be generated is JWT token you will have to validate the token.
Validate Token
You need to validate the token in the .Net core Middle ware. Every token issued has a payload and your app middleware will verify every incoming token and reject if it's not able to validate. Your middle ware will fill the claims principle which can be used in your application to validate the authorization as well e.g. roles (if user has authorization to access particular api). You would put "authorize" attribute on top of controller and it will do the job.
You can validate the token manually or some identity provider gives automatic validation e.g. Azure Ad will validate the token and fill the claims principle without doing much effort by simply adding Azure ad nuget package.
There are heaps of example if you simply google. Tokens can be confusing so i would suggest you understand tokens e.g. id_token , access_token , refresh token . Authentication flows and claims. It would become easier if you understand the token types and flows. I am attaching very simple example just to give you idea.
Example

Is there any Spring boot Security specific solution to my needs?

I started using spring 4 mounth ago, I want to try any idea that I got and now I want to know if what I m trying to do is possible, if so is there any specific security mechanism that I m not yet aware of.
I successfully implmented a secured API that have Authentication and Authorization using the basic auth and ssl enabled, this API handles a cruds of pizza fabrication with it ingerdiants.
Now I Want to create another API that will handle billing of pizza so this api is going to use the previous.
this reuse principle got my attention is it possible to implement a security mechanisme in my second api that ask my first if my current user is loged in ?
the scenario in my head is looking like
user authentication and authorization in API pizza
user ask api bill to get a bill of a pizza (some request with headers ...)
the bill api asks the pizza api if the request source is already authenticated
pizza api answers if is authenticated or not
bill api store in memory the authentication state
By googling I m not sure if the spring security token based authentication is a solution.
NB: I m using only http Request there is no form or front end
High-level overview of the solution would be as follows:
Establish OAuth2 Server and Zuul gateway.
Service "A" authenticates against OAuth2 authentication server and calls service "B"'s Rest endpoint via Zuul gateway (i.e Zuul proxies call to Service "B") with OAuth2 token stored in the session and adds OAuth2 token in HTTP "Authorization" header on request.
Zuul looks up service "B" endpoint, propagates service "A"'s OAuth2 token using it's filter by inspecting Headers and and forwards call with the same token in "Authorization" header.
Service "B", which is protected resource, receives request, inspects headers and validates recived token against OAuth2 server.
You can also let Zuul automatically propagate OAuth2 access tokens further and authorize incoming requests against the OAuth2 service by using the #EnableOAuth2Sso annotation.

API gateway and microservice authentication

How API Gateway and Micro services works.
Could anyone explain the basic flow of Micro service architecture with Gateway. I couldn't find the proper answer.
Say we have auth server and customer micro service running on separate instances and in front of all the services we have an API gateway.
My question is.
when user try to log in using username and password, the API gateway call auth server and return the access token to user.
Then user trying to access the specific url (/customers - customer micro service) that is running on separate instance.
what API Gateway do ?
validate the token with auth server and get the user id and pass the request to customer service with the user id ?
OR
validate the token and pass the request to customer microservice with the access token ? and customer microservice responsible is to the check the user id (Make an HTTP call to auth server) ?
I think that the most common approach is to use API gateway also as a security gateway, which means that API gateway is responsible for SSL termination and token validation. If token validation is successfully you can put user ID or user API key as a header and forward the request to microservice. Moreover you may also decide to perform not only authentication but also authorisation on the API gateway (usually with help of API management solutions).
Regarding your option #2 - I see no point in validating token 2 times. Best practise is to perform security validations on the edge, because in case of failed validation you use less resources (reject earlier)
To Answer your question , it is close to option #2 that you have mentioned . The API gateway will generally check the validity of the authentication token and then pass over the request to your micro-service . However you need to decide at design time if your micro-service will also do another level of verification of the token.
Please do note that the API gateway will not be enforcing Authorization , the authorization is something that your micro-service will have to enforce.

Resources