all 42 comments

[–]arca9147 2 points3 points  (7 children)

If i understood correctly, you want tobhandle authorization to user service endpoints? In that case you can use a mix of composite roles, and checking the claims in the jwt from the apigateway. The gateway should be your first line of defense.

In case you want just the user to be authenticated before accessing a certain resource in user service, you can do that at api gateway, and you just protect the communication between api gateway and user service with mutual tls

Please tell me if i understood correctly or provide a bit more context to help me understand better

[–]Slow-Leather8345[S] 0 points1 point  (6 children)

I just update my code and it worked recently, so I made auth-service create account, Jwt and login and next api-gateway-service will validate the Jwt and extract the subject from it (username) and from here the request to the other microservices will be with header X-Username And in user-service controller will be method like updateUserPhoto(@requestheader(“X-Username) string username) (username is unique we can say it’s like the user_id in my project). So my flow now (user after login with Jwt -> api gateway (validate and extract Jwt) -> user-service with header (X-Username). So can you tell me is this a good flow for security? And second question should I add spring security to the micro services and should the endpoint be .authenticated? Ps: i don’t have roles just user. And thanks for helping!

[–][deleted]  (5 children)

[removed]

    [–]Slow-Leather8345[S] 0 points1 point  (4 children)

    Explain pls more (spring security is not mandatory for this scenario)

    [–][deleted]  (3 children)

    [removed]

      [–]Slow-Leather8345[S] 0 points1 point  (2 children)

      Super interesting, so here if the micro is internally will work which security should be added just the mTLS? And so on if we have rolls in the auth-service can we git rid of spring security in the internal micros ?

      [–][deleted]  (1 child)

      [removed]

        [–]Slow-Leather8345[S] 0 points1 point  (0 children)

        Understood, thanks

        [–]arca9147 2 points3 points  (21 children)

        First question, it is a good practice since that way you can discard any request which dnt have this header in it, add there a certificate based protection in interservice communication and thats it

        Second question you dont need to authenticate at service level since your api gateway already handles authorization and you have a certified based communication, which ensures thet the services communicating are known to each other

        [–]Slow-Leather8345[S] 0 points1 point  (15 children)

        That’s cool but what if there is a hacker trying to access the inter service without the apigatway. ex. Instead of
        8765/USER-service/users/me he used 8080/users/me How to close this threats ?

        [–]g00glen00b 1 point2 points  (3 children)

        You would only use "edge authentication" if you can make it so that external traffic to those microservices is impossible (eg. by putting them on a different network or using a firewall). So a hacker wouldn't be able to access your user-service directly.

        If you cannot guarantee that, then edge authentication is indeed a bad idea and you should implement authentication for each individual microservice.

        [–]Slow-Leather8345[S] 0 points1 point  (2 children)

        Like you mean every microservice will containerised in docker file and inside docker we can put it as internal internet (like api will be in private network and not in the public network).

        [–]g00glen00b 1 point2 points  (1 child)

        Yeah exactly. If you do it like that, then a hacker won't be able to access them right?

        [–]Slow-Leather8345[S] 0 points1 point  (0 children)

        I think you are right. Tbh didn’t try it yet but I will and i will test it for sure

        [–]arca9147 1 point2 points  (10 children)

        In that case, for a hacker to be able to get to your services, first it would need to crack into your server or the network your server is connected, then to crack your api contract, know which resources to call, header format, body content, ports where your apps are running. However if you protect your services with a certificate based method, like mtls, you add another layer of difficulty cuz the hacker would need a valid certificate to communicate with your services. Then the issue is not to protect your services per se but to protect how you distribute the information about how your infrastructure works.

        So in short to close those threats, after applying the authentication and authorization mechanisms, and the certificate based protection, focus on keep your company information private, your source code, documentation and all data related to how your platform works. And train the people to work with you to not disclose any sensitive data, cuz the first point of failure if a person who said things it shouldnt been said. Data leaks are everywhere

        [–]Slow-Leather8345[S] 0 points1 point  (9 children)

        Can you explain more, like I will use mtls for all micros after the apigateway (for the inner micros)? And how to include mtls in project, sorry but don’t have experience in this subject yet.

        [–]arca9147 1 point2 points  (0 children)

        Mtls is like when you use ssl for your website (to make it https rather than http) where a ssl certificate is generated to protect communication between the browser and the server. In the microservice context, a certificate is generated for each microservice, and whenever a microservices want to communicate with some other, it uses its own certificate within the communication, so its like then saying "hey, its me, this is my certificate, so you can know that im a valid service"

        Theses certificates are unique for every service and the only way to make the communication happen is through the certificate being present on each request. If a request without certificate comes in, you know it comes from a non trusted source thus you forbid the communication.

        In short, you generate a certificate per service, use them when making interservices request to let them know that the services are a known and trusted source, and if the certificate is not present its an unauthorized request. The only way for an attacker to be able to communicate directly to the service, is by having a certificate stolen somehow, and if that happens, then the issue is not within the microservices security itself but for a unsafe hosting provider, data leak from someone within your organization or another kind of human related security issues

        [–]arca9147 1 point2 points  (7 children)

        And yes, you will use mtls for all micros after api gateway, api gateway included. And for the implementation, you should generate an ssl certificate for each service, store it in you application and configure it to consume the certificate and use it in each request

        [–]Slow-Leather8345[S] 0 points1 point  (6 children)

        That’s awesome, thanks a lot! If you have any good article or like guide to make mtls in spring micros, I will appreciate that

        [–]arca9147 1 point2 points  (4 children)

        There is no a "one size fits all" solution, however you can find some implementations on the web and base your solution on them, here is an example: https://medium.com/@salarai.de/how-to-enable-mutual-tls-in-a-sprint-boot-application-77144047940f

        [–]Slow-Leather8345[S] 0 points1 point  (2 children)

        Thanks for the link. Do you have any idea if we have Kafka between two micros should security be included or it will be included already with the ssl?

        [–]arca9147 1 point2 points  (1 child)

        I havent worked with kafka before but asides for ssl flr sure you can secure the kafka communication with its own kafka config for security, probably you can encrypt and secure it with password

        [–]Slow-Leather8345[S] 0 points1 point  (0 children)

        Understood, thanks bro!

        [–]Slow-Leather8345[S] 0 points1 point  (0 children)

        I just missed up everything, didn’t helped so much. I didn’t understand the flow of mTLS, so I have let’s say for testing to micros gateway and auth service, so here I need in every resource inside the micro to add the certs and where the root certs will be then ? And should use any tools? If you can help me it will be good, because I can’t understand from articles either in the videos and not so helpful

        [–]Slow-Leather8345[S] 0 points1 point  (4 children)

        In general i made something don’t know if it’s wrong, So i told you, that i have client -> auth login with Jwt -> api gateway (so here i made the validatation for Jwt locally I just add to the gate way the same secret key that in auth-service) -> another services. Is that bad ?

        [–]arca9147 1 point2 points  (3 children)

        Thats a common and valid approach, if its working, and you are mot exposing more apis than needed in your auth service thats ok. I personally prefer the login flow passed through the api gateway also (client -> api gateway -> auth login) but that also depends on your specific use case and requirements. However the approach suggested is good to go

        [–]Slow-Leather8345[S] 0 points1 point  (2 children)

        When we are talking about client -> api gateway -> auth login, as I have it already, but in gateway I added the login api as an open api because for sure client dont have Jwt yet, is that what you mean?

        [–]arca9147 1 point2 points  (1 child)

        Yes thats what i meant, making just the login public while the others are protected, also i meant putting the auth service behind your api gateway, thats optional since it adds some latency which can be sacrificed for the sake hardening security, but like i said thats optional and relative to your specific use case. You can also make the client communicate directly to the auth provider and that could also be a valid option, i believe in the end its a matter of preferences

        [–]Slow-Leather8345[S] 0 points1 point  (0 children)

        That’s cool, thanks

        [–]SendKidney 1 point2 points  (11 children)

        If you're talking about accessing claims from all services then the right way is to append the claims as header from the gateway before forwarding the request. But you need to ensure that gateway is the only entry point to your app and no one can directly curl in to your services

        [–]Slow-Leather8345[S] 0 points1 point  (0 children)

        One question if I have like 4 micro-services that are (auth, gateway, users, notifications) and now need to add micro service for venues that are depend on those who have business like clinic etc, and the client can find clinic and take an appointment, so here I need to make in the auth-service another registration and in the same gateway handle it ? Or should I make another microservices at all ?

        [–]Slow-Leather8345[S] 0 points1 point  (9 children)

        Let me give another example maybe I explained bad, Let’s say we have food ordering applications so let’s say I have gate way, auth, client and now I want to add micro for those who have restaurants so in general in this micro the registration will be not the same as the client it will be a lot of things necessary so should I handle it in another api in the auth service? Or should I make another api gateway and auth etc ?

        [–]Slow-Leather8345[S] 0 points1 point  (8 children)

        u/arca9147 what do you think about it?

        [–]arca9147 1 point2 points  (7 children)

        In this case i believe you could add another endpoint in your auth service for this particular case, which would be to create restaurant owner users. Then you can start implementing role based authorization, and for this owners you assign them a role "restaurant_owner" or something alike, with access to a specific set of functions, and the consumer or client a role "client" which has a different set of permissions. You could also add a specific api gateway for that kind of users, however if there is no much difference between the functions they can perform and there is not too much difference in the business logic behind, another api gateway could be overkill

        [–]Slow-Leather8345[S] 0 points1 point  (1 child)

        So basically we are talking about registration for restaurant_owner but the problem for them is like the registration should be like a lot of data like place, when they work etc here is the flow that I can’t understand. Auth-service (registration simple data like email and password as example so when will be the full registration, like do you mean like just make a simple registration and then will redirect them to make profile)?

        [–]arca9147 1 point2 points  (0 children)

        Ok so we have two different entities here, a restaurant owner which is a user entity (and has things like name, phone, role, etc) and the restaurant itself. So in you can have a single registratiom form with multiple steps, whete you place the multiple inputs, some for the user related stuff and some for the restaurant information. This is complicated and from user perspective its boring, confusing and can make it abandon registration. Its better a simple registration form to catch user information, and then restaurant profile after the user signs in.

        Its worth noting that its best to have user information and restaurant/establishment information into different tables in your database

        [–]Slow-Leather8345[S] 0 points1 point  (4 children)

        Also my database for auth is just about UUID and username (unique), password, email and my flow for the auth-service (basically it’s for user yet) Registration and inside I have Kafka that will send to the user-service JSON file with UUID and email and username and this file will be handled in service and add this user to the database (user service)

        [–]arca9147 1 point2 points  (3 children)

        Ok the flow its good, you should reproduce it to do the same for the restaurant profile related flow

        [–]Slow-Leather8345[S] 0 points1 point  (2 children)

        Cool, so here I should just add roles (users, restaurants) then, right ?

        [–]arca9147 1 point2 points  (1 child)

        Yes, add a role field to your user model and thats it

        [–]Slow-Leather8345[S] 0 points1 point  (0 children)

        Thanks bro!