Search Tutorials


Secure Spring Boot Azure Web Application with Managed Identity Authentication + App Registration Example

Secure Spring Boot Azure Web Application with Managed Identity Authentication + App Registration Example

In a previous tutorial we had deployed spring boot application as azure web application. We had also implemented a tutorial to secure the deployed azure web application using Azure AD.
In this tutorial we will be securing the deployed azure web application using app registration and managed identity. We will be creating spring boot projects - employee consumer and employee producer. The employee-producer exposes a GET rest endpoint which returns a json. The employee consumer consumes this json.
Secure Spring Boot Azure Web Application
We will then be deploying the employee producer and employee consumer as azure web app services.
OpenaAI
We will then be securing the deployed azure web app services using managed identity and azure app registration.
Secure Spring Boot Azure Web Application with Managed Identity Authentication + App Registration Example

Video

This tutorial is explained in the below Youtube Video.

Implementation

Let us create spring boot maven project for employee-producer and employee-consumer.

employee-producer

The maven project will be as follows-
Secure Spring Boot Azure Web Application with Managed Identity Authentication
The pom.xml will be as follows-
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.javainuse</groupId>
	<artifactId>employee-producer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.2</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>17</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

	</dependencies>

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


</project>
Create a model class named employee
package com.javainuse.model;

public class Employee {
	private String empId;
	private String name;
	private String designation;
	private double salary;

	public Employee() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getEmpId() {
		return empId;
	}

	public void setEmpId(String empId) {
		this.empId = empId;
	}

}




Create a controller class which exposes a GET REST endpoint and returns the employee json.
package com.javainuse.controllers;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.javainuse.model.Employee;

@RestController
public class TestController {

	@RequestMapping(value = "/employee", method = RequestMethod.GET)
	public Employee firstPage() {

		Employee emp = new Employee();
		emp.setName("emp1");
		emp.setDesignation("manager");
		emp.setEmpId("1");
		emp.setSalary(3000);

		return emp;
	}

}
Finally create the spring bootstrap class.
package com.javainuse;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootHelloWorldApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootHelloWorldApplication.class, args);
	}
}
We want to start this application on port 80.
server.port=80
Start the spring boot application. If we now go to localhost/employee the employee json is returned as follows-
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Employee Consumer

The maven project will be as follows-
Secure Spring Boot Azure Web Application with Managed Identity Authentication
The pom.xml will be as follows-
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.javainuse</groupId>
	<artifactId>employee-consumer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.2</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>17</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		

	</dependencies>

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


</project>
Define a controller class which will consume the deployed employee-producer json.
package com.javainuse.controllers;

import java.io.IOException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
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.RestController;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerControllerClient {

	@RequestMapping(value = "/consume", method = RequestMethod.GET)
	public String getEmployee() throws RestClientException, IOException {

		String baseUrl = "http://localhost/employee";
		RestTemplate restTemplate = new RestTemplate();
		ResponseEntity<String> response=null;
		try{
		response=restTemplate.exchange(baseUrl,
				HttpMethod.GET, getHeaders(),String.class);
		}catch (Exception ex)
		{
			System.out.println(ex);
		}
		System.out.println(response.getBody());
		return response.getBody();
	}

	private static HttpEntity<?> getHeaders() throws IOException {
		HttpHeaders headers = new HttpHeaders();
		headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
		return new HttpEntity<>(headers);
	}
}
Define the spring bootstrap class as follows-
package com.javainuse;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootHelloWorldApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootHelloWorldApplication.class, args);
	}
}
Start the application and call localhost:8080/consume. We get the output as
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Deploy spring boot applications as azure webapps

Deploy employee-producer to azure web app

Create the docker file as follows-
# Stage 1: Build the application
FROM maven:3.8.3-openjdk-17-slim AS build
WORKDIR /home/app
COPY . /home/app
RUN mvn -f /home/app/pom.xml clean package

# Stage 2: Run the application
FROM openjdk:17-jdk-slim
COPY --from=build /home/app/target/*.jar /usr/local/lib/app.jar
EXPOSE 80
ENTRYPOINT ["java","-jar","/usr/local/lib/app.jar"]
Build Docker image
docker build -t javainuse-producer .

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Login to azure portal
az login

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Login to azure ACR
az acr login -n javainuseapp.azurecr.io

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Tag image with ACR name
docker tag javainuse-producer javainuseapp.azurecr.io/javainuse-producer

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Push image to ACR.
docker push javainuseapp.azurecr.io/javainuse-producer

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Go to azure portal and create azure web app.
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication

Deploy employee-consumer to azure web app

For employee consumer we will be making in the controller class so that it consumes the azure web app deployed employee-producer service.
package com.javainuse.controllers;

import java.io.IOException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
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.RestController;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerControllerClient {

	@RequestMapping(value = "/consume", method = RequestMethod.GET)
	public String getEmployee() throws RestClientException, IOException {

		String baseUrl = "https://javainuse-producer-e7bhcffqdaf2bxa5.canadacentral-01.azurewebsites.net/employee";
		RestTemplate restTemplate = new RestTemplate();
		ResponseEntity<String> response=null;
		try{
		response=restTemplate.exchange(baseUrl,
				HttpMethod.GET, getHeaders(),String.class);
		}catch (Exception ex)
		{
			System.out.println(ex);
			return ex.toString();			
		}
		System.out.println(response.getBody());
		return response.getBody();
	}

	private static HttpEntity<?> getHeaders() throws IOException {
		HttpHeaders headers = new HttpHeaders();
		headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
		return new HttpEntity<>(headers);
	}
}
Create the docker file as follows-
# Stage 1: Build the application
FROM maven:3.8.3-openjdk-17-slim AS build
WORKDIR /home/app
COPY . /home/app
RUN mvn -f /home/app/pom.xml clean package

# Stage 2: Run the application
FROM openjdk:17-jdk-slim
COPY --from=build /home/app/target/*.jar /usr/local/lib/app.jar
EXPOSE 80
ENTRYPOINT ["java","-jar","/usr/local/lib/app.jar"]
Build Docker image
docker build -t javainuse-consumer .

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Login to azure portal
az login

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Login to azure ACR
az acr login -n javainuseapp.azurecr.io

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Tag image with ACR name
docker tag javainuse-consumer javainuseapp.azurecr.io/javainuse-consumer

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Push image to ACR.
docker push javainuseapp.azurecr.io/javainuse-consumer

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Go to azure portal and create azure web app.
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication
We get the output as follows
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Add Authentication provider to employee producer

Create a new app registration in azure portal as follows-
Secure Spring Boot Azure Web Application with Managed Identity Authentication
Next we attach this app registration to employee-producer. Go to Settings -> Authentication. Add new identity provider as follows. In this we add the app registration that we just created.
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication
If we now try to access the employee producer using employee-consumer we get 401 error code.
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Allow employee-consumer to access employee-producer using managed identity

Create a managed identity named java-identity.
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Edit the employee-producer identity provider, to allow access to the managed identity client id.
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Secure Spring Boot Azure Web Application with Managed Identity Authentication
Next we attach the managed-indentity to employee consumer.
Secure Spring Boot Azure Web Application with Managed Identity Authentication
In the pom.xml add the following dependencies-
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.javainuse</groupId>
	<artifactId>employee-consumer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.2</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>17</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>com.azure</groupId>
			<artifactId>azure-identity</artifactId>
			<version>1.5.5</version>
		</dependency>

	</dependencies>

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


</project>
Update the employee-consumer controller code as follows-
package com.javainuse.controllers;

import java.io.IOException;

import com.azure.core.credential.TokenCredential;
import com.azure.identity.ManagedIdentityCredentialBuilder;
import com.azure.core.credential.TokenRequestContext;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
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.RestController;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerControllerClient {

	@RequestMapping(value = "/consume", method = RequestMethod.GET)
	public String getEmployee() throws RestClientException, IOException {
		try {
			// Use the specific managed identity by name
			TokenCredential credential = new ManagedIdentityCredentialBuilder()
					.clientId("68502659-cf25-48df-b7c1-426d9dd36d6e") // Use the client ID of javainuse identity
					.build();

			// Get token (adjust the scope as needed for your API)
			TokenRequestContext tokenRequestContext = new TokenRequestContext();
			tokenRequestContext.addScopes("de01e85d-d818-4efc-8f69-17768d078cb5/.default");

			String token = credential.getToken(tokenRequestContext).block().getToken();
			System.out.println("---Hello----");
			System.out.println(token);
			System.out.println("---Hello----");
			String baseUrl = "https://javainuse-producer-e7bhcffqdaf2bxa5.canadacentral-01.azurewebsites.net/employee";
			RestTemplate restTemplate = new RestTemplate();
			ResponseEntity<String> response = null;

			try {
				response = restTemplate.exchange(baseUrl, HttpMethod.GET, getHeaders(token), String.class);
			} catch (Exception ex) {
				System.out.println("API call error: " + ex);
				return "Error calling API: " + ex.getMessage();
			}

			System.out.println(response.getBody());
			return response.getBody();

		} catch (Exception ex) {
			System.out.println("Token acquisition error: " + ex);
			return "Error getting token: " + ex.getMessage();
		}
	}

	private static HttpEntity<?> getHeaders(String token) throws IOException {
		HttpHeaders headers = new HttpHeaders();
		headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
		headers.set("Authorization", "Bearer " + token);
		return new HttpEntity<>(headers);
	}
}
Deploy this image which will be used by the employee consumer web app. If we again try to access the employee producer code using employee consumer we get the output as follows-
Secure Spring Boot Azure Web Application with Managed Identity Authentication

Download Source Code

Download it -
Employee Producer + Azure Authentication Example
Employee Consumer + Azure Authentication Example