Article

Building and Deploying React Client Extensions in Liferay with OAuth2 using Microservice Client Extensions

Krunal Parmar
Krunal ParmarApr 30, 2026

Introduction

In today’s enterprise applications, microservices help systems remain modular, independent, and scalable.

Liferay’s Client Extension framework lets us connect external services using technologies like React and Spring Boot, without tightly linking them to the core platform. With OAuth2, it helps secure communication between the frontend and backend services.

By combining Microservice Client Extensions with OAuth2 User Agent Applications, we can expose protected APIs and consume them directly from UI components.

This blog walks through how to configure a Spring Boot Client Extension to define OAuth2 and secured APIs, and how a React Client Extension can consume those APIs using Liferay’s OAuth client, enabling secure communication without needing to handle token generation manually.

Prerequisites

  • Liferay DXP/Portal 7.4+
  • Basic knowledge of Liferay Client Extensions
  • Configured microservice client extension in workspace
  • Gradle

Environment Requirements

  • Java
  • Liferay

Part 1 : Spring Boot Microservice Client Extension

Step 1 : Create the .yaml file

Let’s assume you already have a microservice client extension configured in your Liferay Workspace.

  • Create the client-extension.yaml file :
1 assemble:
2    - fromTask: bootJar
3
4 liferay-oauth2-spring-boot-oauth2:
5    .serviceAddress: localhost:58081
6    .serviceScheme: http
7    name: OAuth2 Spring Boot Microservice
8    scopes:
9        - Liferay.Headless.Admin.User.everything
10        - Liferay.Headless.Admin.Workflow.everything
11    type: oAuthApplicationUserAgent

Step 2 : Create API in the rest controller

1@RestController
2@RequestMapping("/api/jokes")
3public class JokeController {
4    private static final Log _log = LogFactory.getLog(JokeController.class);
5    @GetMapping("/random")
6    public ResponseEntity<Map<String, String>> getRandomJoke(@AuthenticationPrincipal Jwt jwt) {
7        //write your business logic
8        log(jwt, _log, json);
9        return new ResponseEntity<>(response, HttpStatus.OK);
10    }
11}

Why @AuthenticationPrincipal?

Liferay sends an OAuth2 access token, and Spring Security extracts the authenticated user from it.

Step 3 :Configure External Reference Code

Add in application-default.properties

liferay.oauth.application.external.reference.codes= liferay-oauth2-spring-boot-oauth2

Step 4 : Build and Deploy the client extension

  • Open a terminal window.
  • Navigate to your client extension project directory.
  • Build the Client Extension
  • Run the following command from your project’s root directory :
1../../gradlew build
  • To deploy the extension to your Liferay instance, run :
1../../gradlew deploy

Step 5 : Start the Microservice Application

After deploying the client extension, you need to start the microservice.

• Open a terminal and navigate to the microservice client extension directory.

• Run the following command to start the application :

1../../gradlew bootRun

What Happens After Deployment?

Based on the configuration, Liferay creates :

  • OAuth2 Application
  • User Agent Application
  • Client ID

Verify OAuth Application

Go to :

Control Panel → OAuth2 Administration

Part 2: React Client Extension

Step 1: Configure React Client Extension

1assemble:
2    -   from: build/static
3        into: static
4oauth-react-widget:
5    friendlyURLMapping: oauth-react
6    htmlElementName: oauth-react-widget
7    instanceable: false
8    name: OAuth React Widget
9    portletCategoryName: category.client-extensions
10    type: customElement
11    urls:
12        -   index.*.js
13    useESM: true

Step 2 : Implement OAuth2 in React

1import React from 'react';
2import * as OAuth2 from '@liferay/oauth2-provider-web/client';
3function JokeComponent() {
4	const [joke, setJoke] = React.useState('');
5	React.useEffect(() => {
6		OAuth2.FromUserAgentApplication('liferay-oauth2-spring-boot-oauth2')
7			.then((oAuth2Client) => {
8				oAuth2Client?.fetch('/api/jokes/random')
9					.then((response) => response.json())
10					.then((data) => {
11						setJoke(data.joke);
12					});
13			})
14			.catch((error) => {
15				console.error('Error fetching joke:', error);
16			});
17	}, []);
18	return !joke ? (
19		<div>Loading...</div>
20	) : (
21		<div>
22			<h2>Secure Joke</h2>
23			<p>{joke}</p>
24		</div>
25	);
26}
27export default JokeComponent;

Step 3 :Build and Deploy React Client Extension

  • Open a terminal window.
  • Navigate to your client extension project directory.
  • Build the Client Extension
  • Run the following command from your project’s root directory :
1../../gradlew build
  • To deploy the extension to your Liferay instance, run :
1../../gradlew deploy

How OAuth2 Authorizes the Request

  • React requests an OAuth client using Liferay’s OAuth2 client library.
  • Liferay checks the user session and generates an access token.
  • Token is sent with API request.
  • The backend microservice validates the token before processing the request.
  • Response is returned.

Conclusion

Using Microservice Client Extensions, we can easily configure an OAuth2 application in Liferay and expose secured APIs from a Spring Boot service. React Client Extensions can then consume these APIs using Liferay’s OAuth client, which handles access token generation.

The backend checks the token before handling the request, so it stays secure. We don’t have to manage authentication ourselves, and the frontend and backend stay loosely connected.

© 2026 IGNEK. All rights reserved.

Ignek on LinkedInIgnek on InstagramIgnek on FacebookIgnek on YouTubeIgnek on X