- iDempiere 12 能接 Microsoft Entra(前 Azure AD),而且是核心內建的 OIDC SSO(plugin
org.idempiere.ui.sso.oidc),純視窗設定、零程式碼。 - 不用碰公司 AAD —— 用免費個人 Entra 租戶(免信用卡)建一個測試 App 就能驗真 Azure。
- 最容易卡死的是兩個開關:SysConfig
ENABLE_SSO=Y(預設 N)和該設定的IsDefault=Y。缺一個都不會轉址。 - 登入認人靠
name(顯示名稱)claim 對AD_User.Name—— 名字對不上就「登入過了卻找不到人」。 - 改設定後要 Cache Reset + 全新無痕;要看真相請
curl看是 302 還是 200,別信瀏覽器畫面。
「iDempiere 到底能不能跟公司的 Azure AD 整合登入?還是得換 Odoo?」這是很多人在把開源 ERP 放進企業身分體系時會問的第一個問題。答案很直接:iDempiere 12 原生就支援 Microsoft Entra ID(舊稱 Azure AD)的 OpenID Connect 單一登入(SSO),不用寫外掛、不用改原始碼,填一張視窗就好。這篇是我在自己的 iDempiere 12 上,對「真」的 Entra 租戶從頭跑通一次的完整實戰紀錄,包含幾個文件沒寫、但你一定會踩到的坑。
iDempiere 能不能接 Microsoft Entra(AAD)?
能,而且是核心內建。很多人以為 iDempiere 接 AAD 要找第三方外掛,其實 SSO 框架就在核心 repo 裡:驗證框架在 org.adempiere.base/.../sso/,OIDC provider 是內建的 org.idempiere.ui.sso.oidc。所有設定集中在一張「SSO Configuration」視窗(資料表 SSO_PrincipalConfig),而且有一個專為 Azure 準備的 Authorization Tenant ID 欄位。Azure 支援自 iDempiere 8.2(2021)就進了核心,release-12 開箱即有。
機制上,iDempiere 扮演 OIDC Relying Party:身分驗證交給 Entra,登入後把回傳的身分對應到 iDempiere 的 AD_User。這跟企業「身分集中 Entra、能力分散在各系統」的架構完全吻合 —— 延伸閱讀我先前寫的 Dify 企業落地:AAD / SSO / 分級 RAG 的授權架構,同一套 Entra 身分可以同時罩住 Dify、iDempiere 等後端。
不用碰公司 AAD:用免費個人 Entra 租戶測
公司的 AAD 通常不能讓你隨便加 redirect URI 或建測試帳號。好消息是:任何人都能用個人 Microsoft 帳號(Outlook/Hotmail)建一個免費 Entra 租戶,基本 free tier 不需要信用卡。進 entra.microsoft.com,用個人帳號登入就有一個預設目錄可用。這樣你能對「真」的 Azure 端到端驗證,完全不動到公司資源;之後要正式上線,只要把租戶/用戶端/密鑰三個值換成公司 App Registration 的即可,其餘設定原封不動。
Entra 端:建 App Registration,拿三個值
在 Entra 建一個 App Registration(帳戶類型選「僅此組織目錄中的帳戶 / 單一租戶」),重新導向 URI 平台選 Web,填 iDempiere 的登入頁網址。註冊完到「概觀」抄兩個值,再去「憑證及祕密」產一組 client secret 抄第三個值:
| 要拿的值 | 在 Entra 哪裡 |
|---|---|
| Tenant ID(目錄/租用戶識別碼) | App → 概觀 |
| Application (client) ID | App → 概觀 |
| ⚠️ Client Secret 的「值(Value)」 | App → 憑證及祕密(離開頁面就看不到,立刻複製) |
⚠️ 關鍵鐵則:Azure 只會把使用者導回「已登記在該 App Registration」的 redirect URI。iDempiere 的登入回呼網址一定要逐字登記進 App 的 Authentication 清單,少一個字元就會被擋,回你 AADSTS50011。
iDempiere 端:SSO Configuration 欄位對應
用最上方搜尋框打 SSO 開啟「SSO Configuration」視窗(選單路徑:System Admin → General Rules → Security)。供應商下拉只有一個 OpenID Connect 是正常的 —— Azure 就是走 OIDC 這條,靠底下的 Discovery URI + Tenant ID 指向 Entra。逐格對應如下:
| 視窗欄位 | 填什麼 |
|---|---|
| SSO Provider | OpenID Connect |
| Tenant ID | Entra 的 Directory (tenant) ID |
| Application Client ID | Application (client) ID |
| Application Secret Key | client secret 的 Value |
| Application Redirect URIs | https://<host>/webui/index.zul |
| Application Discovery URI | 見下方(必須以 .well-known/openid-configuration 結尾) |
| Monitor / Felix 兩格 | 留空 |
Discovery URI 的格式(把 {tenantId} 換成你的 Tenant ID);beforeSave 會驗證結尾,不對就存不進去:
https://login.microsoftonline.com/{tenantId}/v2.0/.well-known/openid-configuration
還有一個設計上的巧妙:redirect URI = 登入頁 = /webui/index.zul。filter SSOWebUIFilter 是判斷「請求 URI 結尾是 index.zul」就攔截觸發 SSO,所以同一個網址同時是使用者登入頁、也是 Azure 驗證完導回來的落點。
兩個真正的開關 —— ENABLE_SSO 與 IsDefault
這是整篇最重要、也最容易卡死的地方。光把 SSO_PrincipalConfig 填好存檔,是不會有任何反應的。要能自動轉址到 Microsoft,四個條件缺一不可:
ENABLE_SSO = Y(預設 N)—— 總開關。沒開整段 SSO 邏輯是死的,填再多設定都沒反應。
IsDefault = Y —— 實測證實是關鍵開關(不是只看「有幾筆 active」)。
SSO_SHOW_LOGINPAGE 不是 Y(預設不存在=false)—— 是 Y 會強制停在帳密頁不轉址。
其中 IsDefault 這條特別值得記一筆:我原本讀 master 原始碼,以為自動轉址只看「有幾筆 active 設定」、跟 IsDefault 無關。結果實測打臉 —— 單一 active 設定、只切 IsDefault,行為完全不同。這種「源碼跟實跑行為不一致」的情況,永遠以實跑為準。乾淨的 A/B 證據如下:
| IsDefault | curl /webui/ 的回應 |
結果 |
|---|---|---|
| Y | HTTP 302 → login.microsoftonline.com | ✅ 轉去 Microsoft |
| N | HTTP 200 → iDempiere 帳密頁 | 🚫 不轉址 |
使用者對應與逃生門
驗證通過後,iDempiere 要把 Entra 的身分對應到本地使用者。對應邏輯在 OIDCPrincipalService.getUserName():
USE_EMAIL_FOR_LOGIN=N(預設)→ 拿 token 的name(顯示名稱) claim 對AD_User.Name=Y→ 拿emailclaim 對AD_User.EMail
快速測試技巧:把 Entra 測試帳號的「顯示名稱」直接設成一個現有 AD_User 的登入名(例如 SuperUser),就能一步對上、免在 iDempiere 另建使用者。名字對不上,就會出現「Azure 登入明明成功、iDempiere 卻說找不到人」的經典坑。
/webui/admin 也會走到帳密登入頁當備援。
用 curl 驗證,別信瀏覽器
改完設定「看起來沒生效」,十之八九是快取假象:設定清單和 ENABLE_SSO 都有 cache,舊分頁重整還是拿到舊值。正確做法是 Cache Reset + 開全新無痕,而看真相的方式是直接 curl 打 server 看它回 302 還是 200:
$ curl -s -o /dev/null -D - "https://your-idempiere/webui/" | grep -iE '^HTTP|^location'
HTTP/2 302
location: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
?scope=openid+profile+email
&response_type=code
&redirect_uri=https%3A%2F%2Fyour-idempiere%2Fwebui%2Findex.zul
&client_id={your-client-id}
&prompt=login ...
看到 302 帶著正確的 client_id、redirect_uri、scope,就代表 server 端已經在運作 —— 這時瀏覽器還是舊畫面,純粹是本機快取,關掉所有無痕視窗重開就好。整條閉環(登入 → Microsoft 驗證 → 認出使用者 → 選角色 → 登出)在我這台 release-12 全跑通了。
那要不要換 Odoo?
Odoo 對 AAD 的整合更成熟(官方逐版本文件、auto-provision、屬性對應開箱即用),但如果你已經在用 iDempiere、也熟它的模型與客製,那沒有為了 SSO 換 ERP 的理由 —— iDempiere 的 OIDC 是核心內建、純設定、剛剛也親手驗證可行。真正的取捨在整體生態與客製深度,不在「能不能接 AAD」這一題。等到要搬進公司,只換三個值就好,其餘照本文設定不動。
發佈留言