使用 OpenID Connect 使用 Microsoft Entra ID 保護 WebSphere Liberty/Open Liberty 應用程式
本文說明如何使用 OpenID Connect (OIDC) 使用 Microsoft Entra ID 保護 IBM WebSphere Liberty/Open Liberty 應用程式。
在本文中,您將學會如何:
- 使用 Microsoft Entra ID 設定 OIDC 提供者。
- 使用 OIDC 保護 WebSphere Liberty/Open Liberty 應用程式。
- 執行及測試 WebSphere Liberty/Open Liberty 應用程式。
必要條件
- Azure 訂用帳戶。 如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。
- 至少具有雲端應用程式管理員Microsoft Entra 角色的 Azure 身分識別。 如需詳細資訊,請參閱 列出Microsoft Entra 角色指派 和 Microsoft Entra 內建角色。
- Microsoft Entra 租用戶。 如果您沒有現有的租使用者,請參閱 快速入門:設定租使用者。
- 已安裝類似 Unix 作業系統的本機電腦,例如 Ubuntu、macOS 或 Windows 子系統 Linux 版。
- Git。
- Java SE 實作版本 21 或更新版本 - 例如 OpenJDK 的Microsoft組建。
- Maven 3.9.3 版或更新版本。
使用 Microsoft Entra ID 設定 OIDC 提供者
OpenID Connect 是業界標準驗證通訊協定,Microsoft Entra ID 支援。 在本節中,您會使用 Microsoft Entra ID 來設定 OIDC 提供者,以搭配 WebSphere Liberty/Open Liberty 應用程式使用。 在稍後的章節中,您會使用 OIDC 來驗證和授權您 Microsoft Entra 租使用者中的使用者,來設定 WebSphere Liberty/Open Liberty 應用程式。
在 Microsoft Entra 租使用者中建立使用者
首先,遵循如何建立、邀請和刪除使用者中的步驟,在Microsoft Entra 租使用者中 建立兩個使用者。 您只需要建立 新的使用者 區段。 當您流覽本文時,請使用下列指示,然後在您在 Microsoft Entra 租使用者中建立用戶之後返回本文。
若要建立使用者以作為應用程式中的「系統管理員」,請使用下列步驟:
- 當您在 [建立新的使用者] 區段中觸達 [基本] 索引卷標時,請使用下列步驟:
若要建立使用者以作為應用程式中的「使用者」,請重複這些步驟,但使用下列值:
- 針對 [ 用戶主體名稱],輸入 user。
- 針對 [ 顯示名稱],輸入 [使用者]。
在 Microsoft Entra ID 中註冊應用程式
接下來,遵循快速入門:使用 Microsoft 身分識別平台 註冊應用程式中的步驟來註冊應用程式。 當您流覽本文時,請使用下列指示,然後在註冊並設定應用程式之後返回本文。
- 當您到達 [ 註冊應用程式 ] 區段時,請使用下列步驟:
- 針對 [支持的帳戶類型],選取 [僅限此組織目錄中的帳戶] (僅限默認目錄 - 單一租使用者)。
- 註冊完成時,請 儲存應用程式 (用戶端) 識別碼 和 目錄 (租使用者) 識別碼 值,以供稍後在應用程式組態中使用。
- 當您到達 [ 新增重新導向 URI ] 區段時,請略過目前的步驟。 您稍後會在本文本機執行及測試範例應用程式時新增重新導向 URI。
- 當您到達 [ 新增認證 ] 區段時,請選取 [ 新增客戶端密碼 ] 索引標籤。
- 當您新增客戶端密碼時,請記下 [客戶端密碼 ] 值,以便稍後在應用程式組態中使用。
將應用程式角色新增至您的應用程式
然後,依照將應用程式角色新增至您的應用程式中的 步驟,在令牌中接收應用程式角色,以將應用程式角色新增至您的應用程式。 您只需要宣告應用程式的角色,並將使用者和群組指派給Microsoft Entra 角色一節。 當您流覽本文時,請使用下列指示,然後在宣告應用程式的角色之後返回本文。
當您觸達 應用程式 區段的宣告角色時,請使用 應用程式角色 UI 來建立系統管理員和一般使用者的角色。
當您觸達 [ 將使用者和群組指派給 Microsoft Entra 角色] 區段時,請使用下列步驟:
請勿遵循將應用程式角色新增至您的應用程式中的任何 其他步驟,並在令牌中接收它們。
使用 OpenID Connect 保護 WebSphere Liberty/Open Liberty 應用程式
在本節中,您會使用 OIDC 保護 WebSphere Liberty/Open Liberty 應用程式,以驗證並授權您 Microsoft Entra 租使用者中的使用者。 您也會瞭解如何使用角色型存取控制 (RBAC) 讓使用者存取應用程式的某些部分。 應用程式會使用 Jakarta Servlet 規格的程式設計安全策略設定。 Jakarta EE 也支援 RESTful Web 服務。 如需保護 RESTful Web 服務應用程式相關文章的參考,請參閱後續步驟一節。
本快速入門的範例 WebSphere Liberty/Open Liberty 應用程式位於 liberty-entra-id 存放庫中的 GitHub 上。
啟用驗證和授權以保護應用程式
應用程式具有index.html中定義的歡迎頁面資源,如下列範例程式代碼所示。 未經驗證的用戶可存取此頁面。 歡迎頁面的根路徑位於 /
。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Greeting</title>
</head>
<body>
<h1>Hello, welcome to Open Liberty/WebSphere Liberty 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>
從歡迎頁面,用戶可以登入應用程式以存取配置檔頁面。 歡迎頁面具有以用戶或系統管理員身分登入的連結。連結分別位於 /profile/user
和 /profile/admin
。
/profile/user
和 /profile/admin
鏈接都會指向 ProfileServlet.java 中定義的配置檔 servlet,如下列範例程式代碼所示。 此 servlet 只能透過使用註釋和批註jakarta.servlet.annotation.ServletSecurity
jakarta.servlet.annotation.HttpConstraint
來存取已驗證的使用者。 屬性 rolesAllowed = {"users"}
指定只有具有安全性角色 users
的已驗證使用者才能存取 /profile
路徑。 已驗證的用戶會自動在 Liberty 組態檔中指派users
角色server.xml。
package com.example;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.HttpConstraint;
import jakarta.servlet.annotation.ServletSecurity;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.ibm.websphere.security.social.UserProfileManager;
import java.util.List;
@WebServlet(name = "ProfileServlet", urlPatterns = {"/profile/user","/profile/admin"})
@ServletSecurity(value = @HttpConstraint(rolesAllowed = {"users"},
transportGuarantee = ServletSecurity.TransportGuarantee.CONFIDENTIAL))
public class ProfileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
List<?> roles = UserProfileManager.getUserProfile().getIdToken().getClaims().getClaim("roles",
List.class);
String path = request.getServletPath();
if (path.equals("/profile/admin") && (null == roles || !roles.contains("admin"))) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
String username = request.getUserPrincipal().getName();
request.setAttribute("name", username);
request.setAttribute("roles", roles);
request
.getRequestDispatcher("/profile.jsp")
.forward(request, response);
}
}
配置檔 servlet 會從標識元令牌擷取使用者的角色,並在用戶嘗試存取/profile/admin
路徑時檢查使用者admin
是否有角色。 如果用戶沒有 admin
角色,servlet 會傳回 403 禁止錯誤。 在其他情況下,servlet 會擷取使用者的名稱,並將要求轉送至具有用戶名稱和角色的配置檔頁面。
配置文件頁面定義於 profile.jsp,如下列範例所示。 這個頁面會顯示用戶的名稱和角色。 配置文件頁面也有位於的註銷連結 /logout
。 配置文件頁面是撰寫 JSP (Jakarta Server Pages)。 請注意頁面中表達式的使用 ${}
方式。 ${}
表示使用 Jakarta 運算式語言 (EL)。 轉譯頁面時,EL 表達式會取代為對應變數的值。 如需 EL 規格的參考,請參閱後續步驟一節。
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>Profile</title>
</head>
<body>
<h1>Hello, ${name}</h1>
<h2>Roles</h2>
<ul>
<c:forEach var="role" items="${roles}">
<li>${role}</li>
</c:forEach>
</ul>
<h1>
<b><a href="/logout">Sign out</a></b>
</h1>
</body>
</html>
當使用者選取要註銷的連結時,應用程式會呼叫LogoutServlet.java中定義的註銷 servlet,如下列範例程式代碼所示。 註銷 servlet 會呼叫 request.logout()
方法來註銷用戶,然後將使用者重新導向至歡迎頁面。
package com.example;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.HttpConstraint;
import jakarta.servlet.annotation.ServletSecurity;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "LogoutServlet", urlPatterns = "/logout")
@ServletSecurity(value = @HttpConstraint(rolesAllowed = {"users"},
transportGuarantee = ServletSecurity.TransportGuarantee.CONFIDENTIAL))
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
request.logout();
response.sendRedirect("/");
}
}
執行及測試 WebSphere Liberty/Open Liberty 應用程式
在本節中,您會執行及測試 WebSphere Liberty/Open Liberty 應用程式,以瞭解它如何搭配 Microsoft Entra ID 作為 OIDC 提供者使用。
將重新導向 URI 新增至應用程式註冊
若要在本機成功執行及測試應用程式,您必須將重新導向 URI 新增至應用程式註冊。 請遵循快速入門:使用 Microsoft 身分識別平台 註冊應用程式,並使用下列值中的 <新增重新導向 URI>一節中的指示:
- 針對 [ 設定平臺],選取 [Web]。
- 針對 [重新導向 URI],輸入
https://localhost:9443/ibm/api/social-login/redirect/liberty-entra-id
。
準備範例
使用下列步驟來準備範例應用程式:
使用下列命令從 GitHub 複製範例應用程式:
git clone https://github.com/Azure-Samples/liberty-entra-id cd liberty-entra-id git checkout 2024-09-26
如果您看到關於處於中斷連結的 HEAD 狀態的訊息,則可放心忽略此訊息。 此訊息只是表示您已取出標籤。
使用下列命令來定義下列環境變數,其中包含您稍早記下的值:
export CLIENT_ID==<application/client-ID> export CLIENT_SECRET=<client-secret> export TENANT_ID=<directory/tenant-ID>
這些環境變數提供 WebSphere Liberty/Open Liberty 中 OIDC 內建支援的值。 自由 server.xml 中對應的 OIDC 組態會顯示在下列範例中。
<oidcLogin id="liberty-entra-id" clientId="${client.id}" clientSecret="${client.secret}" discoveryEndpoint="https://login.microsoftonline.com/${tenant.id}/v2.0/.well-known/openid-configuration" signatureAlgorithm="RS256" userNameAttribute="preferred_username" />
如果組態檔中未定義變數的值,WebSphere Liberty/Open Liberty 會遵循其命名慣例,從環境變數讀取值。 如需命名轉換的詳細資訊,請參閱 變數替代優先順序。
執行 WebSphere Liberty/Open Liberty 應用程式
您可以使用 來執行應用程式 liberty-maven-plugin
。 若要執行應用程式,請選取下列其中一種方法:
注意
若要讓 WebSphere Liberty/Open Liberty 連線到 Microsoft Entra ID,請務必在定義上一節所示環境變數的殼層中執行 命令。
以開發模式執行應用程式:
mvn liberty:dev
以執行時間模式執行應用程式:
mvn liberty:run
如果您想要嘗試不同的模式,請使用 Ctrl+C 停止應用程式,然後在另一個模式中執行應用程式。
測試 WebSphere Liberty/Open Liberty 應用程式
執行應用程式之後,使用私人索引標籤開啟網頁瀏覽器並流覽至 https://localhost:9443
。 由於憑證是自我簽署的,您可能會看到憑證的相關警告。 您可以放心地忽略警告並繼續進行網站。
您應該會看到歡迎頁面,其中包含以使用者或系統管理員身分登入的連結。使用私人索引標籤可避免污染您在一般瀏覽器中可能擁有的任何現有Microsoft Entra ID 活動。
收集兩位用戶的認證
在本文中,Microsoft Entra ID 會使用每個使用者的電子郵件地址作為使用者標識碼進行登入。 使用下列步驟來取得系統管理員使用者和一般使用者的電子郵件地址:
- 以至少 雲端應用程式系統管理員 的身分登入 Microsoft Entra 系統管理中心。
- 如果您有多個租使用者的存取權,請使用 頂端功能表中的 [設定 ] 圖示 ( ) 切換至您想要從 [目錄 + 訂 用帳戶] 功能表註冊應用程式的租使用者。
- 流覽至 [身分>識別使用者>所有使用者]。
- 在清單中找出系統管理員使用者,然後加以選取。
- 找出 [ 用戶主體名稱] 欄位。
- 使用欄位值旁的複製圖示,將使用者的電子郵件地址儲存到剪貼簿。 儲存值以供日後使用。
- 若要取得一般使用者的電子郵件位址,請遵循相同的步驟。
使用系統管理員用戶的密碼,以及您在建立使用者時所設定的一般使用者。
練習應用程式的功能
使用下列步驟來練習功能:
選取 [ 以使用者身分登入] 連結。 使用您稍早建立的一般使用者登入。 登入之後,Microsoft Entra ID 會將您重新導向至配置檔頁面,您可以在其中看到您的名稱和角色。
如果這是第一次登入,系統會提示您更新密碼。 請遵循指示來更新您的密碼。
如果您收到組織 提示,則需要額外的安全性資訊。依照提示下載並設定 Microsoft Authenticator 應用程式,您可以選取 [ 稍後 詢問] 以繼續測試。
如果您收到 要求的許可權提示,請檢閱應用程式所要求的許可權。 選取 [ 接受 ] 以繼續測試。
選取 [註銷 ] 以註銷應用程式。 註銷之後,系統會將您重新導向至歡迎頁面。
選取 [ 以系統管理員身分登入] 連結。 Microsoft Entra ID 會將您重新導向至登入頁面。 使用您稍早建立的系統管理員使用者登入。 登入之後,Microsoft Entra ID 會將您重新導向至類似的配置檔頁面,並具有不同的角色
admin
。再次註銷,並嘗試使用您稍早建立的一般使用者以 系統管理員 身分登入。 您應該會看到錯誤訊息,因為一般用戶沒有
admin
角色。
清除資源
本文不會引導您在 Azure 上部署應用程式。 雖然有Microsoft Entra ID 資源,但是沒有 Azure 資源可清除應用程式。 若要在 Azure 上部署應用程式,您可以遵循下一節中參考的指引。
當您完成此範例應用程式的資源時,請使用下列步驟來清除Microsoft Entra ID 資源。 拿掉未使用Microsoft Entra ID 資源是重要的安全性最佳做法。
- 依照移除向 Microsoft 身分識別平台 註冊的應用程式中的步驟,移除您建立的應用程式註冊。 您只需要遵循移除組織所撰寫應用程式一節中的步驟。
- 拿掉應用程式註冊的動作也應該刪除企業應用程式。 如需刪除企業應用程式的詳細資訊,請參閱 刪除企業應用程式。
- 依照如何建立、邀請和刪除使用者中的 步驟,刪除您所建立的使用者。
下一步
在本快速入門中,您會使用 OIDC 使用 Microsoft Entra ID 保護 WebSphere Liberty/Open Liberty 應用程式。 若要深入瞭解,請探索下列資源:
- 在 Azure Container Apps 上使用 Open Liberty 或 WebSphere Liberty 部署 Java 應用程式
- 在 Azure Red Hat OpenShift 上部署 WebSphere Liberty 和 Open Liberty
- 在 Azure Kubernetes Service (AKS) 叢集上使用 Open Liberty 或 WebSphere Liberty 部署 Java 應用程式
- OpenID Connect 驗證與 Microsoft Entra ID
- Microsoft 身分識別平台和 OAuth 2.0 授權碼流程
- 透過社交媒體提供者驗證使用者
- 社交媒體登入 1.0
- OpenID Connect Client 1.0
- 什麼是OpenID Connect
- 以程式設計方式設定安全策略
- 如何使用 Jakarta EE 保護 RESTful Web 服務
- Jakarta 表達式語言