Hasan
Hasan

Reputation: 309

How to propagate User's authentication (and authorization) to other microservices

I've created a microservice (using Spring boot) for landing page. User provides the credentials and upon successful login, he can see the dashboard. I've used RestTemplate in-order to traverse to other microservice from the dashboard. Below is the code snippets:

    @Autowired
private RestTemplate restTemplate;

@GetMapping("/employeeCenter")
public String openEmployeeCenterApp() {
    logger.info("Invoking EmployeeCenter micro-service");
    return restTemplate.getForEntity("http://EMPLOYEE-SERVICE/empCenter/", String.class).getBody();
}

Which is working fine. But I would like to propagate the User's authentication (and authorization) to any other microservices; so that based on the user's privilage, I can show/hide stuffs. What would be the suitable way to do that?

Upvotes: 2

Views: 1659

Answers (2)

Mark Bramnik
Mark Bramnik

Reputation: 42521

There are many concerns here.

When a "landing page" service (let's call it "A") shows the dashboard for user with identity "Foo" and tries to contact an another service "B" which is an another process via Rest template, you should implement the identity propagation of "Foo", its not the job for the spring security. Spring security will help you in authentication / authorization of user "Foo" inside the service "A", but it has nothing to do with identity propagation.

After all, service "B" can be something not written with spring or java at all, or even some external system.

There are many approaches here depending on requirements that usually boil down to:

  1. Rely on the fact that only landing page (service A) is your "gateway" to the outer world and hence on this service requires security

  2. Protect all the services (like putting spring security or any other security component in each service)

  3. Like "1" but differentiate between security gateway and landing page - have two microservices, so that gateway will be protected and will be "opened" to the end users but also to internal communication. The difference is that if you need to call service "B" from service "A" you can do it through the gateway and it will check the security

Another concern here is what exactly means the "act" of calling the service B from service A.

  • One thing is to tell "I'm user Foo (currently in a Service A) and I'm calling B as Foo.
  • Another thing is telling "I'm service A (that has its own identity) and I'm calling service B on behalf of user Foo".

All these question are in domain of security related architecture and many solutions can be adopted. If you have to do such an analysis (although its kind of out of scope for this question) make sure that you understand that performance implications of each approach: - HTTP hops can be expensive - DB hops (in case you have to turn to the database) are expensive Apply caching wherever possible

Now, technically speaking, you should provide some Filter that will add Identity Headers taken from the Thread Local or similar solution if you run reactive stack. So in the most simple situation you can put an identity object on some thread local and get it in the filter to add requests.

So that bottom line when you construct a request in a RestTemplate (that in turn relies on okHttp, Apache Http Client or whatever) it will have additional headers that will provide the identity information (and again its up to you to decide what exactly is an "identity" here).

The service "B" in turn should parse this object again in some kind of filter (ideally before it hits the rest controller if "B" is in spring as well) or even with spring security if you have it installed on Service B, and make its "protection decisions" based on that identity, then again, put it on thread local if B will query other services and so forth.

Upvotes: 2

Dhruv Patel
Dhruv Patel

Reputation: 364

You can try using WebSecurityConfigurerAdapter and override the configuration of AuthenticationManagerBuilder bean which will let you set roles.

This article has a good example: https://www.journaldev.com/8748/spring-security-role-based-access-authorization-example

Upvotes: 0

Related Questions