Cyber Guard
Fight against cyber crime

Microservices Authentication using Cookie

Need of Microservices Authentication using Cookie

Take the example of a servicing centre as shown the bellow picture. When customer calls the Servicing centre for any kind of help then he/she needs to provide consumer details to the call centre representative. The call centre representative validates the consumer details and provides desired solution. If the solution does not work for the customer then the customer needs to call the representative again and provide consumer detail again as the first time call. This process continues if the servicing centre is stateless as HTTP. It sounds weird.

Each request sent by the user needs user’s detail by the end point of HTTP.
HTTP is a Stateless protocol.

Microservice web-server communicate with each other by means of HTTP where HTTP is a stateless protocol means one client sends request through HTTP to server and the server serves the response to the user or client and forgets it. Again when the client comes and sends request there is no connection between two consecutive requests. So to avoid these consequences we use different approach such as Session+Cookie Or JWT (JSON Web Token).

Note: Session+Cookie is limited only for the web application in browser

What is a microservice?

Microservices are an architectural approach to building applications. As an architectural framework, microservices are distributed and loosely coupled, so one team’s changes won’t break the entire app. The benefit to using microservices is that development teams are able to rapidly build new components of apps to meet changing business needs.

To know more click on link provided https://en.wikipedia.org/wiki/Microservices

Create Your own Application by taking this Video Reference

Requirements for building an Application based on Microservices Authentication and Authorization using Cookie

1. Add jbcrypt Dependencies

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>LoanService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>LoanService</name>
<description>Demo project for Spring Boot</description>

<properties>
<java-version>1.8</java-version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mindrot/jbcrypt -->
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.3m</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

2. Creation of Starter Or Main Class

LoanServiceApplication.java

package com.example.office;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class LoanServiceApplication {
public static void main(String[] args) { SpringApplication.run(LoanServiceApplication.class, args); }
}

3. Creation of Controllers

Account.java

package com.example.office.controller;
public class Account {
int accountNo;
long amount;
public int getAccountNo() {
return accountNo;
}
public void setAccountNo(int accountNo) {
this.accountNo = accountNo;
}
public long getAmount() {
return amount;
}
public void setAmount(long amount) {
this.amount = amount;
}
}

AccountError.java

package com.example.office.controller;
public class AccountError {
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

LoanController.java

package com.example.office.controller;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoanController {
@Autowired
HttpSession session;
@RequestMapping(value = "/login",method=RequestMethod.POST)
public ResponseEntity validate(@RequestParam String uid,@RequestParam String pass)
{
HttpHeaders headers = new HttpHeaders();
String cookie="xyz"; 
String hashedCookie=hashPassword(cookie);
int age=60*60*24*7;
headers.add("Set-Cookie",hashedCookie+"; Max-Age="+age);

session.setAttribute("token",cookie);

if(uid.equals("admin") && pass.equals("1234")) 
{ 
ResponseEntity<?> res= ResponseEntity.status(HttpStatus.OK).headers(headers).body("Welcome "+uid); 
return res; 
} 
else 
{ 
ResponseEntity<?> res= ResponseEntity.status(HttpStatus.NOT_FOUND).body("Invalid credentials"); 
return res;
} 
} 
@RequestMapping("allAccount") 
public List<?> getAllAccounts(HttpServletRequest request) 
{ 
String rawCookie = request.getHeader("Cookie"); 
String hashedToken=rawCookie.substring(0,rawCookie.indexOf(";")); String token=(String)session.getAttribute("token"); 

if(checkPass(token,hashedToken)) 
{
List<Account> allAccount=new ArrayList<Account>();
for(int i=0;i<5;i++) 
{ 
Account acc=new Account(); 
acc.setAccountNo(i+1000); 
acc.setAmount((i+100)*200000);
allAccount.add(acc); 
} 
return allAccount; 
} 
else 
{ 
List<AccountError> error=new ArrayList<AccountError>();  AccountError ae=new AccountError();
ae.setMessage("Authorization failed"); 
error.add(ae);
return error;
} 
} 
private String hashPassword(String plainTextPassword)
{ 
return BCrypt.hashpw(plainTextPassword, BCrypt.gensalt());
} 
private boolean checkPass(String plainPassword, String hashedPassword) 
{ 
if (BCrypt.checkpw(plainPassword, hashedPassword)) 
{ 
return true;
} 
else 
{ 
return false; 
} 
}
}

Procedure To Fetch data over Postman with appropriate images

  1. Run The Project In postman and give Request method as “POST” and Request url as “localhost: (port_number)/login”
  2. Click on Body tab and then on form data .
  3. Mention proper key and value to authenticate.
  4. Click on send and get the required “cookie” by clicking on Headers.
  5. Now in another tab give Request method as “GET” and Request url as “localhost: (port_number)/allAccount”.
  6. Click on headers, and in key type “Cookie” and in value paste the cookie you got from post method
  7. Click on Send and Fetch the result.

Note: By default port number is 8080, but it can be changed in application.properties file stating “server.port=(your desired port_number)”.

Get welcome message displayed in Screen when clicking on Send of “POST” method
Get the following Cookie (Set Cookie) when clicking on “Headers” of POST method
Get list of Arrays when provided with proper cookie value in “GET” method

Download full Source Code for Microservices Authentication and Authorization using Cookie | Bcrypt in Microservice Authorization

Download zip

Share

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *