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

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

Related

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

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

How to validate the user in jwt

I have a rest service which stores comments from the users in the database, my architecture is an angular fronted which connects to a load balancer server (zuul) which connects to an auth server to generate the jwt.
With the jwt the frontend generate the requests to the same zuul server with the jwt, this zuul server validate the jwt and if valid will connect to another backend service to store the comment.
The backend service where the comment is stored doesn't have any security validation all endpoints are accessible as the route of this microservices are not going to be exposed? Is there any risk on this?
As there is no jwt reaching the "comment backend service" how can I get the user that actually made the request? Should I implement some kind of filter in the zuul server to get the logged user from the jwt token and include the information in the request that is being sent to the "comment backend service"? If this is possible, any ideas on how to implement it?
Thanks
Regards
By default, Zuul considers the Authorization header as a sensitive header and it will not pass it downstream. So the first thing you need to do is to update Zuul configurations. Read the documentation here.
After that, in each of your downstream service, you need to add the capability to read the JWT token from the Authorization header and extract relevant information such as username, etc.

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.

REST service using Spring Security and Firebase Authentication

Is there a simple way to integrate Firebase Authentication with Spring Security (for a REST service)?
From what I've read, I'll probably need to use a JWT token (obtained via Firebase), use that to authenticate the Spring service, and finally verify the token within the service via Firebase. But I can't find any (simple) documentation on using JWT with Spring Security.
I'd also like to be able to provide an /auth/login endpoint that uses Basic Auth rather than JWT so that I can obtain a JWT token via Firebase using email/password credentials. But this would mean enabling Basic Auth at one endpoint in the service and JWT Auth at all others. Not sure that's possible.
Short answer: no.
Long answer: you should create your own JWT, regardless of Firebase. When you receive a JWT from Firebase, verify its integrity. Then, issue your own based on the data in the token. Then you only need to adapt it to various OAuth providers. This way you can avoid round trips to firebase on each request.
For authenticating the user on each request (stateless auth), you add a filter with highest precedence. From the http request you are filtering, get the JWT and verify its integrity. If it's all good, set the authentication in the SecurityContextHolder.

Resources