Secure Quarkus applications with Microsoft Entra ID using OpenID Connect
This article shows you how to secure Red Hat Quarkus applications with Microsoft Entra ID using OpenID Connect (OIDC).
In this article, you learn how to:
- Set up an OpenID Connect provider with Microsoft Entra ID.
- Protect a Quarkus app by using OpenID Connect.
- Run and test the Quarkus app.
Prerequisites
- An Azure subscription. If you don't have an Azure subscription, create a free account before you begin.
- An Azure identity with at least the Cloud Application Administrator Microsoft Entra role. For more information, see List Microsoft Entra role assignments and Microsoft Entra built-in roles.
- A Microsoft Entra tenant. If you don't have an existing tenant, see Quickstart: Set up a tenant.
- A local machine with a Unix-like operating system installed - for example, Ubuntu, macOS, or Windows Subsystem for Linux.
- Git.
- A Java SE implementation, version 21 or later - for example, the Microsoft build of OpenJDK.
- Maven, version 3.9.3 or later.
Set up an OpenID Connect provider with Microsoft Entra ID
In this section, you set up an OpenID Connect provider with Microsoft Entra ID for use with your Quarkus app. In a later section, you configure the Quarkus app by using OpenID Connect to authenticate and authorize users in your Microsoft Entra tenant.
Create users in Microsoft Entra tenant
First, create two users in your Microsoft Entra tenant by following the steps in How to create, invite, and delete users. You just need the Create a new user section. Use the following directions as you go through the article, then return to this article after you create users in your Microsoft Entra tenant.
To create a user to serve as an "admin" in the app, use the following steps:
- When you reach the Basics tab in the Create a new user section, use the following steps:
For User principal name, enter admin. Save the value so you can use it later when you sign in to the app.
For Mail nickname, select Derive from user principal name
For Display name, enter Admin.
For Password, select Auto-generate password. Copy and save the Password value to use later when you sign in to the app.
Select Account enabled.
Select Review + create > Create. Wait until the user is created.
Wait a minute or so and select Refresh. You should see the new user in the list.
To create a user to serve as a "user" in the app, repeat these steps, but use the following values:
- For User principal name, enter user.
- For Display name, enter User.
Register an application in Microsoft Entra ID
Next, register an application by following the steps in Quickstart: Register an application with the Microsoft identity platform. Use the following directions as you go through the article, then return to this article after you register and configure the application.
- When you reach the Register an application section, use the following steps:
- For Supported account types, select Accounts in this organizational directory only (Default directory only - Single tenant).
- When registration finishes, save the Application (client) ID and Directory (tenant) ID values to use later in the app configuration.
- When you reach the Add a redirect URI section, skip the steps as for now. You add the redirect URI later when you run and test the sample app locally in this article.
- When you reach the Add credentials section, select the Add a client secret tab.
- When you add a client secret, write down the Client secret value to use later in the app configuration.
Add app roles to your application
Then, add app roles to your application by following steps in Add app roles to your application and receive them in the token. You just need the sections Declare roles for an application and Assign users and groups to Microsoft Entra roles. Use the following directions as you go through the article, then return to this article after you declare roles for the application.
When you reach the Declare roles for an application section, use the App roles UI to create roles for the administrator and the regular user.
Create an administrator user role by using the following values:
- For Display name, enter Admin.
- For Allowed member types, select Users/Groups.
- For Value, enter admin.
- For Description, enter Admin.
- Select Do you want to enable this app role?.
Select Apply. Wait until the role is created.
Create a regular user role by using the same steps, but with the following values:
- For Display name, enter User.
- For Value, enter user.
- For Description, enter User.
When you reach the Assign users and groups to Microsoft Entra roles, section, use the following steps:
Select Add user/group.
In the Add Assignment pane, for Users, select user Admin and for Select a role, select role Admin. Then, select Assign. Wait until the application assignment succeeds. You might need to scroll the table sideways to see the Role assigned column.
Repeat the previous steps to assign the User role to user User.
Select Refresh and you should see the users and roles assigned in the Users and groups pane.
You might need to adjust the width of the column headers to make your view look like the image.
Don't follow any other steps in Add app roles to your application and receive them in the token.
Protect a Quarkus app by using OpenID Connect
In this section, you secure a Quarkus app that authenticates and authorizes users in your Microsoft Entra tenant by using OpenID Connect. You also learn how to give users access to certain parts of the app using role-based access control (RBAC).
The sample Quarkus app for this quickstart is on GitHub in the quarkus-azure repository, and located in the entra-id-quarkus directory.
Enable authentication and authorization to secure app
The app has a welcome page resource defined in WelcomePage.java, which is shown in the following example code. This page is accessible to unauthenticated users. The root path of the welcome page is at /
.
@Path("/")
public class WelcomePage {
private final Template welcome;
public WelcomePage(Template welcome) {
this.welcome = requireNonNull(welcome, "welcome page is required");
}
@GET
@Produces(MediaType.TEXT_HTML)
public TemplateInstance get() {
return welcome.instance();
}
}
From the welcome page, users can sign in to the app to access the profile page. The welcome page has links to sign in as a user or as an admin. The links are at /profile/user
and /profile/admin
, respectively. The welcome page UI is defined in welcome.qute.html and shown in the following example:
<html>
<head>
<meta charset="UTF-8">
<title>Greeting</title>
</head>
<body>
<h1>Hello, welcome to Quarkus and Microsoft Entra ID integration!</h1>
<h1>
<a href="/profile/user">Sign in as user</a>
</h1>
<h1>
<a href="/profile/admin">Sign in as admin</a>
</h1>
</body>
</html>
Both /profile/user
and /profile/admin
links point to the profile page resource, defined in ProfilePage.java, as shown in the following example code. This page is accessible only to authenticated users by using the @RolesAllowed("**")
annotation from the jakarta.annotation.security.RolesAllowed
package. The @RolesAllowed("**")
annotation specifies that only authenticated users can access the /profile
path.
@Path("/profile")
@RolesAllowed("**")
public class ProfilePage {
private final Template profile;
@Inject
SecurityIdentity identity;
@Inject
JsonWebToken accessToken;
public ProfilePage(Template profile) {
this.profile = requireNonNull(profile, "profile page is required");
}
@Path("/admin")
@GET
@Produces(MediaType.TEXT_HTML)
@RolesAllowed("admin")
public TemplateInstance getAdmin() {
return getProfile();
}
@Path("/user")
@GET
@Produces(MediaType.TEXT_HTML)
@RolesAllowed({"user","admin"})
public TemplateInstance getUser() {
return getProfile();
}
private TemplateInstance getProfile() {
return profile
.data("name", identity.getPrincipal().getName())
.data("roles", identity.getRoles())
.data("scopes", accessToken.getClaim("scp"));
}
}
The profile page resource enables RBAC by using the @RolesAllowed
annotation. The arguments to the @RolesAllowed
annotation specify that only users with the admin
role can access the /profile/admin
path, and users with the user
or admin
role can access the /profile/user
path.
Both the /profile/admin
and /profile/user
endpoints return the profile page. The profile page UI is defined in profile.qute.html, as shown in the following example. This page displays the user's name, roles, and scopes. The profile page also has a sign-out link at /logout
, which redirects the user to OIDC provider to sign out. The profile page is written using the Qute templating engine. Note the use of {}
expressions in the page. These expressions make use of the values passed to the TemplateInstance
using the data()
method. For more information on Qute, see Qute templating engine.
<html>
<head>
<meta charset="UTF-8">
<title>Profile</title>
</head>
<body>
<h1>Hello, {name}</h1>
<h2>Roles</h2>
<ul>
{#if roles}
{#for role in roles}
<li>{role}</li>
{/for}
{#else}
<li>No roles found!</li>
{/if}
</ul>
<h2>Scopes</h2>
<p>
{scopes}
</p>
<h1>
<b><a href="/logout">Sign out</a></b>
</h1>
</body>
</html>
After sign out, the user is redirected to the welcome page and can sign in again.
Run and test the Quarkus app
In this section, you run and test the Quarkus app to see how it works with Microsoft Entra ID as the OpenID Connect provider.
Add a redirect URI to the app registration
To successfully run and test the app locally, you need to add a redirect URI to the app registration. Follow the instructions in the Add a redirect URI section of Quickstart: Register an application with the Microsoft identity platform, and use the following values:
- For Configure platforms, select Web.
- For Redirect URIs, enter
http://localhost:8080
.
Prepare the sample
Use the following steps to prepare the sample Quarkus app:
Use the following commands to clone the sample Quarkus app from GitHub and navigate to the
entra-id-quarkus
directory:git clone https://github.com/Azure-Samples/quarkus-azure cd quarkus-azure/entra-id-quarkus git checkout 2024-09-26
If you see a message about being in detached HEAD state, this message is safe to ignore. Because this article doesn't require any commits, detached HEAD state is appropriate.
Use the following commands to define the following environment variables with the values you wrote down earlier:
export QUARKUS_OIDC_CLIENT_ID=<application/client-ID> export QUARKUS_OIDC_CREDENTIALS_SECRET=<client-secret> export QUARKUS_OIDC_AUTH_SERVER_URL=https://login.microsoftonline.com/<directory/tenant-ID>/v2.0
These environment variables provide the values for the built-in support of OpenID Connect in Quarkus. The corresponding properties in
application.properties
are shown in the following example.quarkus.oidc.client-id= quarkus.oidc.credentials.secret= quarkus.oidc.auth-server-url=
If the value of a property is blank in
application.properties
, Quarkus converts the property name into an environment variable and reads the value from the environment. For details on the naming conversion, see the MicroProfile Config specification.
Run the Quarkus app
You can run the Quarkus app in different modes. Select one of the following methods to run the Quarkus app. To enable Quarkus to connect to Microsoft Entra ID, be sure to run the command in the shell in which you defined the environment variables shown in the preceding section.
Run the Quarkus app in development mode:
mvn quarkus:dev
Run the Quarkus app in JVM mode:
mvn install java -jar target/quarkus-app/quarkus-run.jar
Run the Quarkus app in native mode:
mvn install -Dnative -Dquarkus.native.container-build ./target/quarkus-ad-1.0.0-SNAPSHOT-runner
If you want to try different modes, use Ctrl+C to stop the Quarkus app and then run the Quarkus app in another mode.
Test the Quarkus app
After the Quarkus app is running, open a web browser with a private tab and navigate to http://localhost:8080
. You should see the welcome page with links to sign in as a user or as an admin. Using a private tab avoids polluting any existing Microsoft Entra ID activity you might have in your regular browser.
Gather the credentials for the two users
In this article, Microsoft Entra ID uses the email address of each user as the user ID for signing in. Use the following steps to get the email address for the admin user and regular user:
- Sign in to the Microsoft Entra admin center as at least a Cloud Application Administrator.
- If you have access to multiple tenants, use the Settings icon ( ) in the top menu to switch to the tenant in which you want to register the application from the Directories + subscriptions menu.
- Browse to Identity > Users > All Users.
- Locate the admin user in the list and select it.
- Locate the User principal name field.
- Use the copy icon next to the value of the field to save the email address of the user to the clipboard. Save the value for later use.
- To get the email address for the regular user, follow the same steps.
Use the passwords for the admin user and regular user that you set when creating the users.
Exercise the functionality of the app
Use the following steps to exercise the functionality:
Select the Sign in as user link. Sign in with the regular user you created earlier. After you sign in, Microsoft Entra ID redirects you to the profile page, where you see your name, roles, and scopes.
If this is the first time you sign in, you're prompted to update your password. Follow the instructions to update your password.
If you're prompted with Your organization requires additional security information. Follow the prompts to download and set up the Microsoft Authenticator app, you can select Ask later to continue the test.
If you're prompted with Permissions requested, review the permissions requested by the app. Select Accept to continue the test.
Select Sign out to sign out from the Quarkus app. Microsoft Entra ID performs the sign out. After you sign out, Microsoft Entra ID redirects you to the welcome page.
Select the Sign in as admin link. Microsoft Entra ID redirects you to the sign-in page. Sign in with the admin user you created earlier. After you sign in, Microsoft Entra ID redirects you to the similar profile page, with a different role
admin
.Sign out again and try to Sign in as admin with the regular user you created earlier. You should see an error message because the regular user doesn't have the
admin
role.
Clean up resources
This article doesn't direct you to deploy your app on Azure. There are no Azure resources to clean up for the app, although there are Microsoft Entra ID resources. To deploy an app on Azure, you can follow the guidance referenced in the next section.
When you finish with the resources for this sample app, use the following steps to clean up the Microsoft Entra ID resources. Removing unused Microsoft Entra ID resources is an important security best practice.
- Remove the app registration you created by following the steps in Remove an application registered with the Microsoft identity platform. You only need to follow the steps in the section Remove an application authored by your organization.
- The act of removing the app registration should also delete the enterprise application. For more information about deleting enterprise applications, see Delete an enterprise application.
- Delete the users you created by following the steps in How to create, invite, and delete users.
Next steps
In this quickstart, you protect Quarkus applications with Microsoft Entra ID using OpenID Connect. To learn more, explore the following resources:
- Deploy a Java application with Quarkus on an Azure Container Apps
- OpenID Connect authentication with Microsoft Entra ID
- Microsoft identity platform and OAuth 2.0 authorization code flow
- Protect a web application by using OpenId Connect (OIDC) authorization code flow
- OpenID Connect authorization code flow mechanism for protecting web applications
- OpenID Connect (OIDC) configuration properties