入組織數(shù)據(jù)到 Backstage 軟件目錄:msgraph 目錄插件完全指南)
從 Microsoft Entra ID 導(dǎo)入組織數(shù)據(jù)到 Backstage 軟件目錄msgraph 目錄插件完全指南【免費(fèi)下載鏈接】backstageBackstage is an open framework for building developer portals項(xiàng)目地址: https://gitcode.com/GitHub_Trending/ba/backstage本指南基于 Backstage 倉(cāng)庫(kù)中的docs/integrations/azure/org.md編寫系統(tǒng)講解如何通過backstage/plugin-catalog-backend-module-msgraph及增量版-msgraph-incremental插件借助 Microsoft Graph API 將 Microsoft Entra ID原 Azure AD租戶中的用戶、群組與組織信息批量導(dǎo)入 Backstage 軟件目錄。讀完本文你將掌握標(biāo)準(zhǔn)與增量?jī)煞N導(dǎo)入方式的選擇與安裝、四種 Microsoft Graph 認(rèn)證方式的配置、用戶/群組的過濾與搜索策略包括path參數(shù)、userGroupMember、loadPhotos等細(xì)節(jié)、利用自定義 Transformer 深度定制實(shí)體映射的方法以及常見故障的排查路徑。功能概述Backstage 的 Catalog軟件目錄支持直接從 Microsoft Entra ID 租戶中攝取組織數(shù)據(jù)——用戶與團(tuán)隊(duì)。該能力由backstage/plugin-catalog-backend-module-msgraph插件提供其核心是MicrosoftGraphOrgEntityProvider實(shí)現(xiàn)位于 MicrosoftGraphOrgEntityProvider.ts。它作為 Catalog 的 EntityProvider 被注冊(cè)到catalogProcessingExtensionPoint按schedule配置周期性調(diào)用 Microsoft Graph API將User、Group以及代表整個(gè)組織的根Group實(shí)體寫入 Catalog。從源碼角度看整個(gè)攝取流程分為三條主鏈路見 org.ts讀取通過MicrosoftGraphClient分頁(yè)拉取用戶與群組數(shù)據(jù)轉(zhuǎn)換由默認(rèn)的defaultUserTransformer、defaultGroupTransformer、defaultOrganizationTransformerdefaultTransformers.ts將 Graph 對(duì)象映射為UserEntity/GroupEntity關(guān)系構(gòu)建buildOrgHierarchy()負(fù)責(zé)雙向修正spec.parent與spec.childrenbuildMemberOf()為每個(gè)用戶補(bǔ)齊傳遞性transitive的群組歸屬關(guān)系最終寫入user.spec.memberOf。攝取的實(shí)體還會(huì)被打上graph.microsoft.com/tenant-id、graph.microsoft.com/group-id、graph.microsoft.com/user-id與microsoft.com/email等注解定義見 constants.ts這些注解是后續(xù)按 Graph 對(duì)象 ID 回查、去重與關(guān)聯(lián)的關(guān)鍵標(biāo)識(shí)。安裝與基礎(chǔ)配置該插件默認(rèn)不會(huì)隨 Backstage 安裝需要手動(dòng)添加到后端包中。# 在 Backstage 根目錄執(zhí)行 yarn --cwd packages/backend add backstage/plugin-catalog-backend-module-msgraph接著在app-config.yaml中添加基礎(chǔ)配置catalog: providers: microsoftGraphOrg: default: tenantId: ${AZURE_TENANT_ID} user: filter: userType eq member group: filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:ceqUnified) schedule: frequency: PT1H timeout: PT50M最后在后端入口注冊(cè)該模塊packages/backend/src/index.tsbackend.add(import(backstage/plugin-catalog-backend)); backend.add(import(backstage/plugin-catalog-backend-module-msgraph));注意對(duì)于大型組織首次全量導(dǎo)入耗時(shí)可能很長(zhǎng)請(qǐng)謹(jǐn)慎設(shè)置過低的frequency/timeout避免任務(wù)超時(shí)中斷。配置結(jié)構(gòu)解析從配置解析源碼 config.ts 可以看到catalog.providers.microsoftGraphOrg下可以聲明多個(gè) provider每個(gè)以唯一 id 為鍵且存在兩種寫法多 provider 寫法推薦microsoftGraphOrg下每個(gè)鍵是一個(gè) provider id如default、production單 provider 簡(jiǎn)化寫法直接在microsoftGraphOrg下平鋪tenantId、clientId等字段源碼通過providersConfig.has(clientId)判斷此時(shí)內(nèi)部使用固定的 provider iddefault。關(guān)鍵配置項(xiàng)對(duì)應(yīng)MicrosoftGraphProviderConfig類型與默認(rèn)值如下配置項(xiàng)說(shuō)明默認(rèn)值targetMicrosoft Graph 基礎(chǔ) URL末尾斜杠會(huì)被自動(dòng)去除https://graph.microsoft.com/v1.0authority認(rèn)證機(jī)構(gòu)地址如https://login.microsoftonline.com無(wú)使用 Azure Identity 默認(rèn)tenantId目標(biāo)租戶 ID必填無(wú)clientId/clientSecret應(yīng)用注冊(cè)的客戶端憑據(jù)二者必須成對(duì)出現(xiàn)否則配置解析直接報(bào)錯(cuò)無(wú)user.filter用戶過濾條件OData$filter無(wú)user.select/user.expand查詢時(shí)拉取的字段 /$expand參數(shù)無(wú)user.path用戶端點(diǎn)路徑usersuser.loadPhotos是否加載用戶頭像trueuserGroupMember.filter/.search按群組成員導(dǎo)入用戶時(shí)的群組過濾/搜索條件無(wú)userGroupMember.path群組成員端點(diǎn)路徑無(wú)group.filter/group.search群組過濾 / 搜索條件無(wú)group.select/group.expand群組字段 /$expand無(wú)group.path群組端點(diǎn)路徑groupsgroup.includeSubGroups是否一并導(dǎo)入匹配群組的子群組falsequeryMode查詢模式basic或advanced進(jìn)階查詢能力basicschedule.frequency/schedule.timeout定時(shí)任務(wù)頻率與超時(shí)ISO 8601 時(shí)長(zhǎng)無(wú)需顯式配置配置解析層還內(nèi)置了若干強(qiáng)校驗(yàn)config.tsuserFilter與userGroupMemberFilter互斥定義了userFilter時(shí)不能再設(shè)置userGroupMemberSearch/userGroupMemberPathqueryMode只能是basic或advancedclientId與clientSecret必須成對(duì)。配置寫錯(cuò)會(huì)在啟動(dòng)階段直接拋出明確錯(cuò)誤便于及早發(fā)現(xiàn)問題。大型租戶的增量導(dǎo)入方案對(duì)于數(shù)據(jù)量極大、無(wú)法一次性把全量數(shù)據(jù)集載入內(nèi)存的 Entra ID 租戶backstage/plugin-catalog-backend-module-msgraph-incremental提供了內(nèi)存友好的替代方案它一頁(yè)一頁(yè)地處理用戶與群組并把odata.nextLink游標(biāo)持久化Pod 重啟后可從上次完成的頁(yè)繼續(xù)導(dǎo)入無(wú)需從頭開始。安裝兩個(gè)依賴yarn --cwd packages/backend add backstage/plugin-catalog-backend-module-incremental-ingestion yarn --cwd packages/backend add backstage/plugin-catalog-backend-module-msgraph-incremental注冊(cè)到后端backend.add(import(backstage/plugin-catalog-backend)); backend.add( import(backstage/plugin-catalog-backend-module-incremental-ingestion), ); backend.add( import(backstage/plugin-catalog-backend-module-msgraph-incremental), );增量 provider 復(fù)用與標(biāo)準(zhǔn)模塊相同的catalog.providers.microsoftGraphOrg配置但不支持userGroupMember*與groupIncludeSubGroups兩類選項(xiàng)若確實(shí)需要這些能力請(qǐng)回退使用MicrosoftGraphOrgEntityProvider。從源碼實(shí)現(xiàn)MicrosoftGraphIncrementalEntityProvider.ts可以看到增量方案的設(shè)計(jì)細(xì)節(jié)定義了MSGraphCursor游標(biāo)類型{ phase: users | groups; nextLink?: string }其中nextLink直接保存 Graph API 返回的odata.nextLink天然編碼了續(xù)傳所需的全部狀態(tài)用戶階段每頁(yè)拉取 999 條USER_PAGE_SIZE 999群組階段每頁(yè)僅拉取 100 條GROUP_PAGE_SIZE 100因?yàn)槿航M階段還要為每頁(yè)上的每個(gè)群組獲取成員較小的頁(yè)尺寸可讓每個(gè)突發(fā)請(qǐng)求控制在時(shí)間預(yù)算內(nèi)實(shí)體名超過 Backstage 63 字符上限時(shí)如日歷/預(yù)訂類賬號(hào)的 UPN會(huì)截?cái)嗟?54 字符并追加 8 位 SHA-1 哈希以保證唯一性通過withLocations()以msgraph:providerId/uid的形式為實(shí)體打上backstage.io/location注解確保實(shí)體可被追蹤與去重。兩種方案對(duì)比如下維度MicrosoftGraphOrgEntityProviderIncremental provider內(nèi)存占用全量數(shù)據(jù)載入 RAM一次僅處理一頁(yè)重啟后續(xù)傳從頭開始從游標(biāo)續(xù)傳userGroupMember*選項(xiàng)支持不支持groupIncludeSubGroups支持不支持適合大型租戶否是使用 Microsoft Graph 認(rèn)證本地開發(fā)環(huán)境本地開發(fā)時(shí)推薦安裝 Azure CLI 或 Azure PowerShell 并完成登錄也可以使用帶 Azure 擴(kuò)展的 VSCode需額外安裝azure/identity-vscode。配置好這些之后插件會(huì)通過 Azure Identity 的默認(rèn)憑據(jù)鏈自動(dòng)完成 Graph API 認(rèn)證無(wú)需配置任何憑據(jù)或授予特殊權(quán)限。如果上述方式都不可行則需創(chuàng)建 App Registration。應(yīng)用注冊(cè)App Registration如果其他認(rèn)證方式均不可用可在 Azure Portal 中創(chuàng)建應(yīng)用注冊(cè)。默認(rèn)情況下插件需要以下 Microsoft Graph 的應(yīng)用程序權(quán)限Application permissions非 Delegated 委托權(quán)限GroupMember.Read.AllUser.Read.All如果組織要求對(duì)這些權(quán)限進(jìn)行管理員同意Admin Consent需要提前完成授權(quán)流程。使用 ClientId/ClientSecret 認(rèn)證時(shí)既可以設(shè)置AZURE_TENANT_ID、AZURE_CLIENT_ID、AZURE_CLIENT_SECRET環(huán)境變量也可以在配置中直接指定microsoftGraphOrg: default: # ... clientId: 9ef1aac6-b454-4e69-9cf5-7199df049281 clientSecret: REDACTED示例中的clientId僅作格式演示請(qǐng)?zhí)鎿Q為你自己的應(yīng)用注冊(cè)值。也可以使用證書而非客戶端密鑰認(rèn)證此時(shí)設(shè)置AZURE_TENANT_ID、AZURE_CLIENT_ID、AZURE_CLIENT_CERTIFICATE_PATH三個(gè)環(huán)境變量即可。托管標(biāo)識(shí)Managed Identity如果部署到支持托管標(biāo)識(shí)且已配置標(biāo)識(shí)的 Azure 資源如 Azure App Services、Azure Container Apps插件會(huì)自動(dòng)拾取托管標(biāo)識(shí)無(wú)需額外配置。當(dāng)應(yīng)用擁有多個(gè)托管標(biāo)識(shí)時(shí)可能需要設(shè)置AZURE_CLIENT_ID環(huán)境變量來(lái)指定 Azure Identity 應(yīng)使用的標(biāo)識(shí)。為托管標(biāo)識(shí)授予與上面應(yīng)用注冊(cè)一節(jié)相同的權(quán)限即可。過濾導(dǎo)入的用戶與群組默認(rèn)情況下插件會(huì)導(dǎo)入目錄中**所有已啟用enabled**的用戶與所有群組已禁用的用戶賬號(hào)accountEnabled eq false會(huì)被自動(dòng)排除。你還可以通過 Graph 的$filter過濾查詢參數(shù)與$search搜索查詢參數(shù)進(jìn)一步定制。任何自定義的user.filter都會(huì)以and方式與基礎(chǔ)過濾條件accountEnabled eq true組合。群組過濾與搜索通過配置search或filter可以獲取更小的群組集合如果同時(shí)提供filter和search則群組必須同時(shí)滿足兩者才會(huì)被導(dǎo)入。microsoftGraphOrg: providerId: group: filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:ceqUnified) search: description:One AND (displayName:Video OR displayName:Drive)如果不只想導(dǎo)入匹配search和/或filter的群組還想一并導(dǎo)入這些群組的成員群組可開啟includeSubGroupsmicrosoftGraphOrg: providerId: group: filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:ceqUnified) search: description:One AND (displayName:Video OR displayName:Drive) includeSubGroups: true除這些群組之外插件還會(huì)為你的組織額外創(chuàng)建一個(gè)根群組所有導(dǎo)入的群組都將是它的子群組對(duì)應(yīng)defaultOrganizationTransformer創(chuàng)建的type: root的 Group 實(shí)體。用戶過濾與按群組成員導(dǎo)入導(dǎo)入用戶有兩種模式。第一種是導(dǎo)入所有匹配filter的用戶對(duì)象基礎(chǔ)過濾accountEnabled eq true會(huì)自動(dòng)應(yīng)用并與自定義過濾條件組合microsoftGraphOrg: providerId: user: filter: userType eq member第二種是導(dǎo)入特定群組的成員用戶對(duì)于每個(gè)匹配search與filter查詢的群組其每位成員都會(huì)被導(dǎo)入。注意只導(dǎo)入直接成員不導(dǎo)入傳遞性成員transient users。microsoftGraphOrg: providerId: userGroupMember: filter: displayName eq Backstage Users search: description:One AND (displayName:Video OR displayName:Drive)需要說(shuō)明的是雖然userGroupMember模式只導(dǎo)入直接成員但在關(guān)系構(gòu)建階段buildMemberOf()org.ts會(huì)結(jié)合已有群組層級(jí)為每個(gè)用戶算出傳遞性的memberOf歸屬鏈——即用戶所屬群組、以及該群組的所有上級(jí)群組都會(huì)被寫入user.spec.memberOf。使用path參數(shù)默認(rèn)情況下 provider 通過 msgraph 的/group與/user端點(diǎn)獲取群組和用戶但可以通過設(shè)置path配置改用其他端點(diǎn)。任何包含/microsoft.graph.group的端點(diǎn)都會(huì)返回正確的群組對(duì)象類型任何包含/microsoft.graph.user的端點(diǎn)都會(huì)返回正確的用戶對(duì)象類型。示例給定如下組織結(jié)構(gòu)可以使用path參數(shù)獲取someRootGroup在所有層級(jí)上的用戶與群組成員配置如下microsoftGraphOrg: providerId: group: path: /groups/{someRootGroup id}/transitiveMembers/microsoft.graph.group user: path: /groups/{someRootGroup id}/transitiveMembers/microsoft.graph.user使用transitiveMembers端點(diǎn)將返回someRootGroup在所有層級(jí)上的全部用戶與群組成員。用戶頭像User photos默認(rèn)情況下插件會(huì)拉取用戶頭像并添加到每個(gè)用戶實(shí)體上。對(duì)于超大型組織這可能不可行——拉取頭像會(huì)耗費(fèi)非常長(zhǎng)的時(shí)間可通過將loadPhotos設(shè)為false關(guān)閉microsoftGraphOrg: providerId: user: filter: ... loadPhotos: false如果使用userGroupMember模式loadPhotos的配置仍應(yīng)放在user:下同時(shí)省略search和filtersmicrosoftGraphOrg: providerId: user: loadPhotos: false userGroupMember: filter: displayName eq Backstage Users search: description:One AND (displayName:Video OR displayName:Drive)自定義實(shí)體轉(zhuǎn)換Transformers攝取的實(shí)體可以通過自定義 transformer 進(jìn)行定制。它們既可以完全替換內(nèi)置邏輯也可以調(diào)用默認(rèn) transformerdefaultGroupTransformer、defaultUserTransformer、defaultOrganizationTransformer實(shí)現(xiàn)見 defaultTransformers.ts后再做微調(diào)。返回undefined即可將對(duì)應(yīng)實(shí)體從 Backstage 中排除。當(dāng)使用自定義 transformer 時(shí)你可能還想調(diào)整 Graph 查詢返回的數(shù)據(jù)可通過以下配置項(xiàng)定制查詢microsoftGraphOrg: providerId: user: expand: manager group: expand: member select: [id, displayName, description]動(dòng)態(tài)配置縮放Provider Config Transformer動(dòng)態(tài)配置縮放允許 msgraph catalog 插件在運(yùn)行時(shí)調(diào)整設(shè)置而無(wú)需重新部署。這對(duì)需要根據(jù)實(shí)時(shí)事件或變化條件更新配置的場(chǎng)景非常有用例如動(dòng)態(tài)調(diào)整同步調(diào)度、過濾條件與搜索參數(shù)以優(yōu)化性能與響應(yīng)性。注意調(diào)整那些并非每次定時(shí)攝取都會(huì)使用的字段如id、schedule不會(huì)產(chǎn)生任何效果。警告在運(yùn)行中動(dòng)態(tài)變更配置可能引入意外后果如系統(tǒng)不穩(wěn)定與配置錯(cuò)誤。請(qǐng)仔細(xì)審查你的 transformer確保其行為符合預(yù)期典型用例過濾條件縮放動(dòng)態(tài)調(diào)整userGroupMember、groupFilter等過濾條件搜索參數(shù)調(diào)整隨時(shí)修改groupSearch、userSelect等搜索參數(shù)。注冊(cè)自定義 TransformerTransformer 通過擴(kuò)展microsoftGraphOrgEntityProviderTransformExtensionPoint配置。該擴(kuò)展點(diǎn)定義于 catalogModuleMicrosoftGraphOrgEntityProvider.ts提供setUserTransformer、setGroupTransformer、setOrganizationTransformer、setProviderConfigTransformer四個(gè)方法均可傳入單個(gè)函數(shù)或按 provider id 分組的Recordstring, Transformer且每種 transformer只能被設(shè)置一次重復(fù)設(shè)置會(huì)拋出錯(cuò)誤。在packages/backend/src/index.ts中注冊(cè)示例import { createBackendModule } from backstage/backend-plugin-api; import { microsoftGraphOrgEntityProviderTransformExtensionPoint } from backstage/plugin-catalog-backend-module-msgraph/alpha; import { myUserTransformer, myGroupTransformer, myOrganizationTransformer, myProviderConfigTransformer, } from ./transformers; backend.add( createBackendModule({ pluginId: catalog, moduleId: microsoft-graph-extensions, register(env) { env.registerInit({ deps: { microsoftGraphTransformers: microsoftGraphOrgEntityProviderTransformExtensionPoint, }, async init({ microsoftGraphTransformers }) { microsoftGraphTransformers.setUserTransformer(myUserTransformer); microsoftGraphTransformers.setGroupTransformer(myGroupTransformer); microsoftGraphTransformers.setOrganizationTransformer( myOrganizationTransformer, ); microsoftGraphTransformers.setProviderConfigTransformer( myProviderConfigTransformer, ); }, }); }, }), );myUserTransformer、myGroupTransformer、myOrganizationTransformer、myProviderConfigTransformer這幾個(gè)函數(shù)來(lái)自下面章節(jié)的示例。Transformer 示例下面給出每種 transformer 的示例。建議在packages/backend/src下創(chuàng)建transformers.ts文件存放這些函數(shù)。首先建立文件的基礎(chǔ)結(jié)構(gòu)為每種 transformer 提供直接透?jìng)髂J(rèn) transformer 的函數(shù)import * as MicrosoftGraph from microsoft/microsoft-graph-types; import { defaultGroupTransformer, defaultUserTransformer, defaultOrganizationTransformer, microsoftGraphOrgEntityProviderTransformExtensionPoint, MicrosoftGraphProviderConfig, } from backstage/plugin-catalog-backend-module-msgraph; import { GroupEntity, UserEntity } from backstage/catalog-model; import { createBackendModule } from backstage/backend-plugin-api; // 群組 transformer轉(zhuǎn)換從 MS Graph 導(dǎo)入的 Group export async function myGroupTransformer( group: MicrosoftGraph.Group, groupPhoto?: string, ): PromiseGroupEntity | undefined { const backstageGroup await defaultGroupTransformer(group, groupPhoto); return backstageGroup; } // 用戶 transformer轉(zhuǎn)換從 MS Graph 導(dǎo)入的 User export async function myUserTransformer( graphUser: MicrosoftGraph.User, userPhoto?: string, ): PromiseUserEntity | undefined { const backstageUser await defaultUserTransformer(graphUser, userPhoto); return backstageUser; } // 組織 transformer將根 MS Graph Organization 轉(zhuǎn)換為 Group export async function myOrganizationTransformer( graphOrganization: MicrosoftGraph.Organization, ): PromiseGroupEntity | undefined { const backstageOrg await defaultOrganizationTransformer(graphOrganization); return backstageOrg; } // Provider 配置 transformer支持修改插件配置 export async function myProviderConfigTransformer( provider: MicrosoftGraphProviderConfig, ): PromiseMicrosoftGraphProviderConfig { return provider; } // 將這些函數(shù)包裝進(jìn)一個(gè) Module便于注入 Catalog 插件 export default createBackendModule({ pluginId: catalog, moduleId: msgraph-org, register(reg) { reg.registerInit({ deps: { microsoftGraphTransformers: microsoftGraphOrgEntityProviderTransformExtensionPoint, }, async init({ microsoftGraphTransformers }) { microsoftGraphTransformers.setUserTransformer(myUserTransformer); microsoftGraphTransformers.setGroupTransformer(myGroupTransformer); microsoftGraphTransformers.setOrganizationTransformer( myOrganizationTransformer, ); microsoftGraphTransformers.setProviderConfigTransformer( myProviderConfigTransformer, ); }, }); }, });群組 Transformer完全替換默認(rèn)邏輯這個(gè)示例完全移除默認(rèn)邏輯替換為自定義實(shí)現(xiàn)——假設(shè)所有群組名都以組織單元前綴命名如Engineering - Team A我們希望丟棄組織單元前綴、并把它用作命名空間export async function myGroupTransformer( group: MicrosoftGraph.Group, groupPhoto?: string, ): PromiseGroupEntity | undefined { // 所有群組都以組織單元前綴命名Engineering - Team A // 我們丟棄群組名中的組織單元并將其用作命名空間 const groupNameArr group.displayName.split( - ); const displayName groupNameArr[1]; // 用連字符替換空格并轉(zhuǎn)為小寫標(biāo)準(zhǔn)化 name 與 namespace const namespace groupNameArr[0].replace( , -).toLowerCase(); const groupName groupNameArr[1].replace( , -).toLowerCase(); return { apiVersion: backstage.io/v1alpha1, kind: Group, metadata: { name: groupName, description: group.description, annotations: {}, }, spec: { type: team, displayName: displayName, email: group.mail, children: [], }, }; }用戶 Transformer復(fù)用內(nèi)置邏輯并微調(diào)這個(gè)示例調(diào)用內(nèi)置邏輯同時(shí)修改用戶名并設(shè)置描述export async function myUserTransformer( graphUser: MicrosoftGraph.User, userPhoto?: string, ): PromiseUserEntity | undefined { const backstageUser await defaultUserTransformer(graphUser, userPhoto); // 確保默認(rèn) transformer 返回了實(shí)體 if (backstageUser) { // 更新描述表明該實(shí)體來(lái)源 backstageUser.metadata.description Loaded from Microsoft Entra ID via MyCustomUserTransformer; // 默認(rèn) transformer 會(huì)把用戶名設(shè)為郵箱地址并替換非法字符user_domain.com // 這里改為郵箱的本地部分去掉域名并轉(zhuǎn)小寫 const newName backstageUser.metadata.name.split(_)[0].toLowerCase(); backstageUser.metadata.name newName; return backstageUser; } return undefined; }組織 Transformer移除組織根群組這個(gè)示例通過返回undefined完全移除組織群組export async function myOrganizationTransformer( graphOrganization: MicrosoftGraph.Organization, ): PromiseGroupEntity | undefined { // 組織 transformer 會(huì)創(chuàng)建一個(gè)群組作為群組關(guān)系樹的根基 // 我們不需要?jiǎng)?chuàng)建它因此返回 undefined 而不是實(shí)體 return undefined; }Provider 配置 Transformer動(dòng)態(tài)擴(kuò)展過濾條件這個(gè)示例擴(kuò)展群組過濾條件確保azure-group-a始終被包含export async function myProviderConfigTransformer( provider: MicrosoftGraphProviderConfig, ): PromiseMicrosoftGraphProviderConfig { // 配置文件中的過濾條件依賴一個(gè)偶發(fā)導(dǎo)致該重要群組導(dǎo)入失敗的屬性 // 確保該群組總能被過濾條件發(fā)現(xiàn) if (!provider.groupFilter?.includes(azure-group-a)) { provider.groupFilter ${provider.groupFilter} or displayName eq azure-group-a; } return provider; }最后把新模塊添加到后端即可// 你的文件里會(huì)有更多內(nèi)容 const backend createBackend(); // ... backend.add(import(./extensions/transformers)); // ... backend.start();需要留意示例中的myProviderConfigTransformer修改了provider.groupFilter對(duì)應(yīng)配置項(xiàng)group.filter這屬于每次定時(shí)攝取都會(huì)使用的字段因此動(dòng)態(tài)調(diào)整能生效而id、schedule等字段的調(diào)整會(huì)被忽略catalogModuleMicrosoftGraphOrgEntityProvider.ts 中擴(kuò)展點(diǎn)文檔亦有同樣說(shuō)明。故障排查沒有數(shù)據(jù)導(dǎo)入首先檢查日志中是否出現(xiàn)Reading msgraph users and groups消息。如果看不到這條日志請(qǐng)檢查 provider 是否已注冊(cè)、schedule是否合法有效。如果看到Read 0 msgraph users and 0 msgraph groups請(qǐng)檢查search與filter參數(shù)。如果看到了開始消息Reading msgraph users and groups但沒有結(jié)束消息Read X msgraph users and Y msgraph groups很可能是數(shù)據(jù)量過大導(dǎo)致任務(wù)耗時(shí)過長(zhǎng)。默認(rèn)行為是導(dǎo)入所有用戶與群組這往往超出實(shí)際需要。可以嘗試導(dǎo)入更小的數(shù)據(jù)集例如filter: displayName eq John Smith。認(rèn)證 / Token 錯(cuò)誤參見 Microsoft 官方文檔《Troubleshooting Azure Identity Authentication Issues》https://aka.ms/azsdk/js/identity/troubleshoot。讀取用戶時(shí)報(bào)錯(cuò)Authorization_RequestDenied - Insufficient privileges確保已為應(yīng)用注冊(cè)或托管標(biāo)識(shí)授予全部所需權(quán)限確保是Application權(quán)限而非Delegated權(quán)限如果組織配置了管理員同意要求請(qǐng)確保已為應(yīng)用程序權(quán)限授予管理員同意如果群組查詢返回的是 Microsoft Teams 群組可能需要額外授予權(quán)限如Team.ReadBasic.All、TeamMember.Read.All如果添加了額外的select或expand字段這些字段可能需要額外授予相應(yīng)權(quán)限。總結(jié)從 Microsoft Entra ID 同步組織數(shù)據(jù)是搭建 Backstage 軟件目錄人員與團(tuán)隊(duì)維度的基礎(chǔ)能力。標(biāo)準(zhǔn)模塊MicrosoftGraphOrgEntityProvider適合中小規(guī)模組織通過豐富的過濾、搜索、path、loadPhotos配置即可精確控制導(dǎo)入范圍對(duì)于超大型租戶msgraph-incremental提供按頁(yè)處理與游標(biāo)續(xù)傳的內(nèi)存友好方案。而四類自定義 Transformer用戶、群組、組織、Provider 配置配合擴(kuò)展點(diǎn)機(jī)制讓實(shí)體映射可以完全貼合企業(yè)自身的組織模型。可進(jìn)一步參考倉(cāng)庫(kù)內(nèi)的相關(guān)文檔與源碼微軟 Graph 集成索引見 docs/integrations/azure/index.md插件實(shí)現(xiàn)與測(cè)試見 plugins/catalog-backend-module-msgraph 與 plugins/catalog-backend-module-msgraph-incremental。【免費(fèi)下載鏈接】backstageBackstage is an open framework for building developer portals項(xiàng)目地址: https://gitcode.com/GitHub_Trending/ba/backstage創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考