Spring Boot Microservices with Keycloak

Micro-service architecture is the new revolution of the software industry and it has been popular topic since later 2015 and now it became the most suited architecture for bigger and complex systems. It is a nice and maintainable replacement to the traditional monolithic (aka all in one) system. As the name says it all, you have to develop and deploy services as small business components, not only in your application layer but also your db layer need to be componentized. Functionality and behaviour should unique to the individual service and dependencies need to be injected via service calls, not using tightly bound db relationships.

Here I am going to explain the basic components of the micro-service system and how to develop a basic functioning micro-service with proper security. In my sample application I have separated my system to few layers

  1. Simple API (Micro-service; you can have multiple MSs)
  2. Service Registry
  3. API Gateway
  4. Identity and Access Management

Later you can introduce more layers to the system, such as config service (Spring Cloud Config), log service (Sleuth), latency and fault tolerance (Hystrix), client side load balancing (Ribbon) etc,  but as a first step I am going to prepare the ground layer for the basic start up system.

You can refer below GIT repository for code setup.

https://github.com/dumindarw/springboot-microservices-starter.git

Step 1 : Configure your KeyCloak Server

Keycloak is an open source Identity and Access Management solution developed by JBoss (on top of WildFly).Download and extract zip/tar file from here “https://www.keycloak.org/” and start up the server using

C:\keycloak-4.5.0.Final\bin
λ .\standalone.bat -Djboss.socket.binding.port-offset=100

Server will startup and on port 8180 . Visit http://localhost:8180/auth/ and create new admin login first.

Visit http://localhost:8180/auth/admin/master/console/#/create/realm and import the JSON file found in above GIT repo (zuul-server/config). It will create realm, clients, roles and users for you (Demo purpose). You can create them manually as you wish.

Step 2 : Start your Eureka Server

Netflix Eureka is a service registry and service discovery component. It will ease our work by registering each micro-service to centralized location and it provides easier way for inter process communication.

Build and run using maven, execute below command withing the project location.

C:\Users\Duminda\spring-workspace\microservices-project\eureka-server
λ mvn install && mvn spring-boot:run

This will start your Eureka server on port 8761

Step 3 : Start your Micro-service

C:\Users\Duminda\spring-workspace\microservices-project\api-service
λ mvn install && mvn spring-boot:run

This will start your API service on port 8080

Step 4 : Start your Zuul API Gateway

Netflix Zuul is a API gateway. It will provide easy routing towards your microservices.

C:\Users\Duminda\spring-workspace\microservices-project\zuul-server
λ mvn install && mvn spring-boot:run

This will start your ZUUL server on port 8762

Step 5 : Get your access token first

We have created a user duminda inside keycloak (Admin console) with password 12345(or you can create your own). We are now able to get the token using below POST request. You can use Postman, SoapUI or CUrl for that.

curl -k -u app-authz-rest-springboot:secret -d "grant_type=password&username=duminda&password=12345" -H "Content-Type: application/x-www-form-urlencoded" http://localhost:8180/auth/realms/spring-boot-quickstart/protocol/openid-connect/token

Above request will return JWT token with some additional data like token expiry time, refresh token etc.

{
  "access_token": "eyJhbGci......",
  "expires_in": 1800,
  "refresh_expires_in": 1800,
  "refresh_token": "eyJhbG .....",
  "token_type": "bearer",
  "not-before-policy": 0,
  "session_state": "1947e319-0793-4cb4-99a6-624d4961a209",
  "scope": "profile email"
}

6. Use above JSON Web Token to call your web service through API Gateway

curl -H "Authorization: Bearer access_token" http://localhost:8762/api/v1/resourceb

Replace access_token with the JWT then you can access  the API resource. Without Authorization token, ZUUL proxy will reject your request and it will not reach to the destination (Microservice1 or Microservice2) and return unauthorized response.

This architecture diagram shows how the system behaves top to bottom.

Architecture Diagram

Note that this is a basic architecture. You can add more components to the architecture and add refresh token capability to the system as well.