Requirement for Microservice client using JWT
In earlier post [ Microservice Authorization by using JWT] we created two end points in a microservice for authorization through spring security. If the microservice uses JWT authorization, then the client of that microservice needs to authenticate and authorize the call through JWT.
Spring boot client of Microservice
- Provide Jasper dependency in pom.xml
- Provide JSP location and extension in application.properties
- Create JSP (index.jsp) for sending credential to authenticator
- Create Controller for sending RestTemplate and receiving ResponseEntity
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.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>Cient</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>Cient</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> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </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>
application.properties
spring.mvc.view.prefix:/WEB-INF/jsp/ spring.mvc.view.suffix:.jsp server.port=8091
Note: port number of client microservice must be different from server microserver for testing in one machine. Hence the the above port of this application is 8091.
index.jsp (create folder in webapps as WEB-INF/jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>MCs Client</title> </head> <body> <form action="/login" method="post"> <h2>User ID<input type="text" name="username"/></h2> <h2>Password<input type="password" name="password"/></h2> <input type="submit" value="login"/> </form> </body> </html>
Controller (JwtClientController.java)
package com.example.jwtClient.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; 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; import org.springframework.web.client.RestTemplate; @RestController public class JwtClientController { ResponseEntity authenticationResponse ; @RequestMapping(value = "/login", method = RequestMethod.POST) public String logintoMCs(@RequestParam String username,@RequestParam String password) { String AUTHENTICATION_URL="http://localhost:8086/authenticate"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>(); map.add("username", username); map.add("password", password); HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers); //ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class ); RestTemplate restTemplate = new RestTemplate(); authenticationResponse = restTemplate.exchange(AUTHENTICATION_URL, HttpMethod.POST, request, String.class); if (authenticationResponse.getStatusCode().equals(HttpStatus.OK)) { //String token = "Bearer " + authenticationResponse.getBody(); return "Login Successfull and Got Token"; } return "Invalid credential"; } @RequestMapping("helloClient") public String helloClient() { if (authenticationResponse !=null && authenticationResponse.getStatusCode().equals(HttpStatus.OK)) { String token = "Bearer " + authenticationResponse.getBody(); String CLIENT_URL="http://localhost:8086/hello"; HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", token); RestTemplate restTemplate = new RestTemplate(); HttpEntity<String> jwtEntity = new HttpEntity<String>(headers); ResponseEntity<String> helloResponse = restTemplate.exchange(CLIENT_URL, HttpMethod.GET, jwtEntity, String.class); if (helloResponse.getStatusCode().equals(HttpStatus.OK)) { String data = helloResponse.getBody(); return data; } } return "Please login"; } }