Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to implement role-based security in microservices architecture [closed]

I have a spring-boot application with 4 microservices, eureka server and a centralized API gateway.

All external traffic is coming via my API gateway to my microservices.

My API gateway (Zuul) is validating and verifying JWT token.

the JWT token is generated by one of my microservices after user login (the users microservice), the token contain the user Id and his roles/authorities.

Now I want to implement role-based security on methods that are present in microservices other than the gateway.

I have tried to use @PreAuthorize but it's not working out of the gateway (obviously in order to make it work I have to set a Spring Security authentication object in the SecurityContextHolder in my microservices and populate it with authorities).

So is there any solution to achieve this type of security?

What is the best design to set up security in microservice architecture?

Authentication at API gateway level and authorization at microservices level?

Do I need to use spring security within the microservices or just pass down the roles (append them to the request) after validating the JWT at API gateway level and for example create my own annotations and use Spring AOP to handle authorization?

like image 473
srijan jain Avatar asked Jan 17 '20 11:01

srijan jain


People also ask

How does security is implemented in microservices architecture?

Within microservices architecture, this means being “secure by design”—keeping security top of mind at every stage of production, from design to build to deployment. When it comes to writing your code, this means implementing a form of continuous stress testing on your architecture.

Which layer do we implement security in microservices?

Implement security using a shared gateway Another approach to implement security for microservices is to use a shared component to implement security for individual microservices. This shared component can be an API gateway or a security gateway that will sit in front of the microservices layer.

What design pattern can be used to prevent security attacks in microservices?

There are several ways of how you can secure communication between services. However, these two are the most common: Mutual Transport Layer Security (mTLS) and Json Web Token (JWT).

How to secure microservices architecture?

Microservices architecture provides teams with a new set of potential security risks which need to be addressed. The best way to secure microservices-based solutions is to implement security best practices and patterns into architecture patterns and design and integrate them into the development lifecycle so that data and apps remain protected.

Do microservices increase the security risk of the application?

One common argument that people bring against the microservices architecture is that it increases the security risk of the application by expanding the risk surface. This is true in the sense that when we have more microservices exposing functionality to external consumers, we have to protect each service from external consumers.

Why is security automation important in microservices?

This is why it’s crucial, at the outset of a microservices build out, to establish some form of automation for scaling security controls. As an organization updates parts of its system, it needs to test it to catch any issues throughout testing.

How are microservices different from monolithic applications?

Looking specifically at security, effective methods for microservices are substantially different than those that work for monolithic applications. For the latter, security teams often use centralized security modules, which cover authentication, authorization, and a range of other critical security measures.


1 Answers

In Spring5 microservices you will be able to find a base to develop a microservice architecture with several of the requisites you are looking for:

  • Registry server using Eureka.
  • Gateway server with Zuul.

Regarding to security, I have developed two different microservices:

  • Spring Oauth2 with Jwt
  • Spring Jwt multi-application security service to work with access and refresh Jwt tokens, with several customizations like: definition of the content of every one, work with JWS or JWE, etc

Most important ones are well documented using Swagger, as you can see here, and all documented APIs are accessible using an unique gateway Url.

For all classes of every microservice, Junit tests were developed.


Security

At this point, I took several decisions:

1. Is not the gateway the microservice that verifies the security.

Because use the gateway as "firewall" is a less flexible approach. I wanted to decide which microservices need security and every one should manage internally the roles can access to every endpoint. In summary, every microservice has to work with the authorization/authentication but it don't need to know how that functionality is done.

2. Specific microservice to deal with the security

As I told you, I developed 2 different ones, because I wanted to "play" with different options/approaches. The most important advantage is the encapsulation, if "tomorrow" I decide to change Jwt by any other option, I will only need to modify those ones, the microservices that use them will keep the same code (I will explain you soon how the integration was done)


Security integration example

I will explain how the security functionality was integrated between:

  • Pizza service easy microservice developed as part of the architecture.
  • Spring Jwt

1. Every application that manages user and roles, will include in the security microservice a folder similar to the next one, to define its models, repositories to get the required information, etc

2. Global endpoints of the security microservice are defined here. As you can see, they work basically with 2 Dtos:

  • AuthenticationInformationDto
  • UsernameAuthoritiesDto

The main advantage, only the security microservice knows the details about how that functionality was done, the other ones that use it will receive a well known Dtos with the required information.

3. In pizza-service, the security integration is mainly defined in the next 3 classes:

  • SecurityContextRepository to get authorization token from the header and send it to the SecurityManager.
  • SecurityManager call to security-jwt-service with the provided "authorization token" (it doesn't know if it is Jwt or any other thing) and receives a well know UsernameAuthoritiesDto (transforming it into an object of the Spring class UsernamePasswordAuthenticationToken)
  • WebSecurityConfiguration global security configuration.

Now you can include in your endpoints the required role based security:

  • Controller example
  • Custom PreAuthorize annotation

Final considerations

  1. pizza-service was developed using Webflux, you can see an equivalent integration based on a MVC microservice one in order-service here (in this case I used the "other security service" but is easy to adapt it).

  2. To improve the security and follow the "Oauth approach", the requests to security-jwt-service need to include the Basic authentication too. As you can see in SecurityManager class:

    private String buildAuthorizationHeader(String username, String password) {
      String auth = username + ":" + password;
      byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());
      return "Basic " + new String(encodedAuth);
    }
    

The table in database to store that information is the same one used to manage the security configuration of every application: security.jwt_client_details

like image 172
doctore Avatar answered Sep 20 '22 18:09

doctore