A microservice client extension is a standalone server process that relies on OAuth 2 for communication with Liferay. The microservice is a resource server and Liferay is the authorization server. See Using OAuth 2 for more information. The sample projects in this demonstration ingest the payload from a protected route in the resource server (microservice) and display it in a frontend widget based on a custom element client extension. To coordinate with the standalone Spring Boot application, two client extension types are used in this example:
Deployable or Runnable Code
Type
Description
Workspace Sample
Deploy the Liferay Sample OAuth Application User Agent
Defines a custom element and requests the payload from the resource server, through its OAuth 2 client code.
liferay-sample-custom-element-2
Note
For convenience, this tutorial uses the ready-to-deploy custom element from the sample workspace. However, the custom element client extension isn’t the focus here. Any frontend technology that can call the authorization server and display the payload from the resource server can be used in place of the custom element.
The resource server has the protected route /dad/joke. On the behalf of the logged in user, the client (i.e., widget) requests an authorization code from the authorization server (Liferay). Once a token is granted, the client communicates with the resource server (Spring Boot application).
Extensions of type oAuthApplicationUserAgent are registered as having a client profile User Agent Application, meaning that the authorization code flow is used.
Now you have the tools to start the microservice and deploy the client extension(s) to Liferay.
Start a new Liferay instance by running
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.132-ga132
Sign in to Liferay at http://localhost:8080. Use the email address test@liferay.com and the password test. When prompted, change the password to learn.
The client-extensions/liferay-sample-etc-spring-boot/client-extension.yaml file defines the microservice client extension project in the sample workspace. Most of the defined client extensions (e.g., the ones with type: *Action) are not needed for this example. The necessary lines from the client-extension.yaml can be boiled down to
assemble:
- fromTask: bootJar
liferay-sample-etc-spring-boot-oauth-application-user-agent:
.serviceAddress: localhost:58081
.serviceScheme: http
name: Liferay Sample Etc Spring Boot Spring Boot OAuth Application User Agent
scopes:
- Liferay.Headless.Admin.Workflow.everything
type: oAuthApplicationUserAgent
The external application/microservice is created with the bootJar command that is available from the Spring Boot Gradle Plugin. The application JAR must be included in the LUFFA for deployment in Liferay SaaS.
The most important part of the client-extension.yaml is in the liferay-sample-etc-spring-boot-oauth-application-user-agent definition. This sets up Liferay as the authorization server, so that the frontend client extension you deploy next can call the resource server’s secure endpoint and display its payload.
The client-extensions/liferay-sample-custom-element-2/client-extension.yaml file defines the custom-element client extension project in the sample workspace:
In Liferay’s log, confirm that the client extension deployed and started:
STARTED liferay-sample-etc-spring-boot_1.0.0 [1588]
2023-06-07 14:24:56.245 INFO [fileinstall-directory-watcher][BundleStartStopLogger:77] STARTED liferay-sample-etc-spring-boot_1.0.0 [1702]
2023-06-07 14:24:56.315 INFO [CM Event Dispatcher (Fire ConfigurationEvent: pid=com.liferay.oauth2.provider.configuration.OAuth2ProviderApplicationUserAgentConfiguration~liferay-sample-etc-spring-boot-oauth-application-user-agent)][InterpolationConfigurationPlugin:135] Replaced value of configuration property 'homePageURL' for PID com.liferay.oauth2.provider.configuration.OAuth2ProviderApplicationUserAgentConfiguration~liferay-sample-etc-spring-boot-oauth-application-user-agent
2023-06-07 14:24:56.365 INFO [CM Event Dispatcher (Fire ConfigurationEvent: pid=com.liferay.oauth2.provider.configuration.OAuth2ProviderApplicationUserAgentConfiguration~liferay-sample-etc-spring-boot-oauth-application-user-agent)][OAuth2ProviderApplicationUserAgentConfigurationFactory:179] OAuth 2 application with external reference code liferay-sample-etc-spring-boot-oauth-application-user-agent and company ID 20096 has client ID id-df5840e5-a91c-dcae-9bd8-873508a699
In addition, messages about the OAuth user agent are logged.
Verify that the OAuth Application User Agent was added to Liferay. Go to Control Panel → OAuth2 Administration.
The Liferay Sample OAuth Application User Agent provides the OAuth 2 authorization needed so that Liferay can access the Spring Boot application’s data through its protected endpoint. All that is needed for Liferay to authorize the application in this case is declaring the external reference code in the application-default.properties:
The microservice is running, and the OAuth2 Application communication channel is now provisioned and available in DXP. This example uses a Custom Element client extension to display the data generated by the microservice. To deploy it,
Go to the client-extensions/liferay-sample-custom-element-2 folder.
When an authenticated user loads a page with the client application on it (the custom element), it requests an authorization code, which is available because of the communication channel configured by the user agent extension (i.e., Liferay is the authorization server). Liferay returns the code, then the client asks for the access token. With the token, the client can access the endpoint in the microservice. The resource server validates the JWT token with Liferay using the JWKS URI endpoint. This is done automatically in the background.
In the DadJoke.js file of the liferay-sample-custom-element-2 client extension, there’s an important call that initiates the authorization pipeline:
This call provides the client with a token, which the client can use as a bearer token when requesting the resources from the /dad/joke route in the resource server. The client code doesn’t need to worry about the location of the server it’s requesting, as this information is encapsulated in the OAuth 2 application. In self-hosted environments it’s declared in the OAuth application user agent’s client-extension.yaml properties, as .serviceAddress and .serviceScheme. In Liferay SaaS environments the resource server is controlled by Liferay, so no declaration of its location is necessary. This sets up authorization code flow for the client and resource server communication, so all that’s left is for the client to call the endpoint in the resource server. DadJoke.js fetches from the /dad/joke route like this:
The OAuth client sends a Jwt token to the microservice, representing the authenticated user. Included is the authorization code, permissions that are granted, and many other details. This sample prints these details to the log for convenience:
This website uses cookies and similar tools, some of which are provided by third parties (together “tools”). These tools enable us and the third parties to access and record certain user-related and activity data and to track your interactions with this website. These tools and the informationcollected are used to operate and secure this website, enhance performance, enable certain website features and functionality, analyze and improve website performance, and personalize user experience.
If you click “Accept All”, you allow the deployment of all these tools and collection of the information by us and the third parties for all these purposes.
If you click “Decline All” your IP address and other information may still be collected but only by tools (including third party tools) that are necessary to operate, secure and enable default website features and functionalities. Review and change your preferences by clicking the “Configurations” at any time.
Visit our Privacy Policy