Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Cloud - how to allow access to endpoint for specific microservice only?

I have simple microservice architecture:

  • edge service
  • service registry
  • auth service (I am using JWT and OAuth2)
  • user service
  • frontend and some core services

When the user tries to log in, the credentials are passing from edge service to auth service. Auth service fetches user's data from user service (using @FeignClient) and if username/password matches, it generates token. Nothing fancy about it.

There a 'little' problem with this approach: the endpoint /api/user/{username} in user service, which is used by auth service to fetch user's data, might be used by any user to get any other user's data (password, roles etc.). The one solution would be somehow create JWT token for auth-service with role AUTH_SERVICE and at the user service side check JWT and if the role is different than AUTH_SERVICE reject the request.

Are there any other solutions?

EDIT

I thought that my design is quite common but apparently I should have been more specific in the first place:

  • Auth-servie is my Authorization Server and the other services are Resource servers
  • I use API gateway pattern and my auth-service is also behin proxy
  • After the client application obtains JWT it adds it to every request and based on that the authentication and authorization is performed; every Resource server has a public key which is used to verify signature; if it's valid, the service knows that JWT has been generated by trusted auth-service and the service based on JWT creates OAuth2Authenication object which contains all the user information

EDIT2:

I ended up merging auth-service to user-service, which was the suggestion given from a couple of SO users. After thinking about it it seemed unnecessary to have a seperate auth-service for just JWT generation. I've accepted @Abhijit Sarkar answer because it has some valid points even though he wasn't right about additional call to auth-service to verify validity of the token.

like image 879
pzeszko Avatar asked Oct 17 '22 09:10

pzeszko


1 Answers

Looks to me that you split your services too thin; this happens, and with time, you start to realize that the services need to be more coarse-grained because of maintenance and performance issues. The cost of another HTTP call from auth to user service, and the overhead of maintaining inter-service auth is not trivial.

IMO, user service can exist for other user information, like address etc if those exist, but auth service should be responsible for managing its own data. This is exactly why Spring Security has a UserDetailsService.

This is really a design choice whether the user credentials and other user information should be in the same table, or even the same database. Different people will give you different answers, but in my opinion and experience, a shared database between a small number of related services is acceptable, especially because these tables are gonna be related by a foreign key (userId). Distributed transaction is pure evil with microservices so I'm not even going there. When you delete/update a user, go for eventual consistency using events.

Edit:

After chatting with the OP, I learned that user service is really the OAuth resource server in his design. It's not clear to him, and thus to me, where is the OAuth authorization server. Regardless, I stand by my suggestion to merge the user service and the auth service.

like image 181
Abhijit Sarkar Avatar answered Nov 12 '22 17:11

Abhijit Sarkar