Backstage v1.39.0-next.3 预发布变更深度解读OAuth2 自定义连接器、Azure 联合凭据与认证回退机制【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstageBackstage 1.39.0 的第 3 个预发布版本v1.39.0-next.3横跨前端认证、集成层、Catalog、搜索、Scaffolder 与 CLI 等多个模块共涉及数十个backstage/*包的同步更新。本文以 docs/releases/v1.39.0-next.3-changelog.md 为骨架逐项解读本版本新增的能力Minor Changes与关键修复Patch Changes并结合仓库源码说明其底层实现与配置方式帮助你在升级到 1.39.0 系列版本前评估影响面并完成对应配置调整。版本说明v1.39.0-next.*属于预发布pre-release版本其版本号带-next.N后缀包版本也以-next.N标记仅用于验证与先行体验正式升级请以稳定的v1.39.0发布为准。本版本核心变更一览变更类型包内容摘要Minorbackstage/core-app-api1.17.0-next.1OAuth2构造支持自定义AuthConnector会话管理可脱离DefaultAuthConnectorMinorbackstage/integration1.17.0-next.3Azure DevOps 集成支持托管身份managed identity联合凭据含system-assignedMinorbackstage/plugin-catalog1.30.0-next.3offset 分页表格显示分页文本移除顶部重复分页栏Minorbackstage/plugin-catalog-backend-module-gitea0.1.0-next.0新增 Gitea Catalog Provider 模块Patchbackstage/plugin-auth-node0.6.3-next.2signInWithCatalogUser新增dangerousEntityRefFallback回退选项Patchbackstage/backend-defaults0.10.0-next.3GithubUrlReader.search支持minimatch完整 glob 语法Patchbackstage/plugin-search-backend-module-elasticsearch1.7.2-next.3修复search.elasticsearch.queryOptions配置未生效问题Patchbackstage/cli0.32.1-next.3rspack 构建启用lazyCompilation与refreshOptionsPatchbackstage/frontend-app-api0.11.2-next.3createSpecializedApp支持忽略未知扩展配置Patchbackstage/plugin-scaffolder-backend1.33.0-next.3Scaffolder 任务重试时重新生成 token一、前端认证为 OAuth2 注入自定义 AuthConnector1.1 变更内容backstage/core-app-api1.17.0-next.1为本版本引入了一项重要的前端认证能力在OAuth2构造函数中传入自定义的AuthConnector实现。此后前端 OAuth2 会话的创建、刷新与销毁将不再绑定在默认的DefaultAuthConnector上而是可以由应用按需接管。在源码 OAuth2.ts 中可以看到这一实现细节OAuth2.create(options)内部通过createAuthConnector判断选项若选项中包含authConnector则直接采用用户实现否则才构建DefaultAuthConnectorprivate static createAuthConnector( options: OAuth2CreateOptions | OAuth2CreateOptionsWithAuthConnector, ) { if (authConnector in options) { return options.authConnector; } // ... 否则基于 configApi/discoveryApi/oauthRequestApi 等 // 构建 DefaultAuthConnector并注入默认 sessionTransform return new DefaultAuthConnector({ /* ... */ }); }对应的类型定义位于 types.tsexport type OAuth2CreateOptionsWithAuthConnector { scopeTransform?: (scopes: string[]) string[]; defaultScopes?: string[]; authConnector: AuthConnectorOAuth2Session; };1.2 AuthConnector 的契约AuthConnector是一个只包含三个方法的轻量接口见 AuthConnector/types.tsexport type AuthConnectorAuthSession { createSession( options: AuthConnectorCreateSessionOptions, ): PromiseAuthSession; refreshSession( options?: AuthConnectorRefreshSessionOptions, ): PromiseAuthSession; removeSession(): Promisevoid; };其中createSession与refreshSession均携带需要申请的scopes: Setstring由实现者负责与认证提供方交互并返回AuthSession。这意味着自定义AuthConnector可以从前端直接调用认证提供方无需经过 Backstageauth-backend的默认代理流程将 token 存储/读取到sessionStorage等自定义存储位置向认证提供方发送自定义请求并自行处理响应。会话管理器RefreshingAuthSessionManager位于 RefreshingAuthSessionManager.ts会调用该连接器完成会话生命周期管理因此只要实现上述三个方法即可无缝替换默认行为。1.3 必须注意的 scope 变换约束变更说明中特别强调了一个约束如果自定义AuthConnector会变换认证提供方返回的 scopes该变换必须与传入OAuth2构造函数的scopeTransform即OAuth2CreateOptions#scopeTransform保持一致否则会话中记录的作用域集合将与实际授权不一致可能导致后续getAccessToken(scope)的授权判断失真。可以参照OAuth2#create(...)内部创建DefaultAuthConnector的方式默认实现通过sessionTransform调用OAuth2.normalizeScopes(res.providerInfo.scope, { scopeTransform })将原始 scope 字符串规范化为Setstring。自定义实现应复用同样的normalizeScopes逻辑可参考该仓库自带的验证用例 OAuth2CustomAuthConnector.test.ts其中CustomAuthConnector在createSession()里使用openLoginPopup打开登录弹窗并通过sessionTransform将原始OAuth2Response转换为OAuth2Session测试验证了自定义连接器下getAccessToken(myScope)能正确返回 token。// 参考实现来自测试用例自定义连接器 同样的 scope 规范化 class CustomAuthConnector implements AuthConnectorOAuth2Session { async createSession() { return await this.sessionTransform( await openLoginPopup({ url: http://my-origin, name: myPopup }), ); } async refreshSession(_?: AuthConnectorRefreshSessionOptions): Promiseany {} async removeSession(): Promisevoid {} } const options: OAuth2CreateOptionsWithAuthConnector { scopeTransform, // 与 OAuth2 构造传入的一致 defaultScopes: [myScope], authConnector: customAuthConnector, }; const oauth2 OAuth2.create(options);1.4 相关修复同包还修复了OAuthRequestDialog在挂载时重复渲染的问题cc119b2涉及OAuthRequestApi弹窗交互的稳定性升级后无需额外配置。二、后端认证dangerousEntityRefFallback 与目录外登录回退2.1 signInWithCatalogUser 新增回退选项backstage/plugin-auth-node0.6.3-next.2为AuthResolverContext.signInWithCatalogUser新增了可选参数dangerousEntityRefFallback当用户在 Catalog 中找不到时将使用调用方提供的实体引用作为回退完成登录。语义上等价于“允许用户在 Catalog 中不存在的情况下仍能登录成功”。其签名定义在 plugins/auth-node/src/types.ts 中用法示例如下return ctx.signInWithCatalogUser( { entityRef: { name: username } }, { dangerousEntityRefFallback: options?.dangerouslyAllowSignInWithoutUserInCatalog ? { entityRef: { name: username } } : undefined, }, );2.2 预置登录解析器统一接入变更说明鼓励各带预置登录解析器sign-in resolver的认证提供方在配置中新增名为dangerouslyAllowSignInWithoutUserInCatalog的布尔标志并在解析器内部启用上述回退。从源码 commonSignInResolvers.ts 可见emailMatchingUserEntityProfileEmail与emailLocalPartMatchingUserEntityName均已支持该选项其optionsSchema使用 zod 声明z.boolean().optional()export const emailLocalPartMatchingUserEntityName createSignInResolverFactory({ optionsSchema: z .object({ allowedDomains: z.array(z.string()).optional(), dangerouslyAllowSignInWithoutUserInCatalog: z.boolean().optional(), }) .optional(), create(options {}) { return async (info, ctx) { const { profile } info; // ... return ctx.signInWithCatalogUser( { entityRef: { name: localPart } }, { dangerousEntityRefFallback: options?.dangerouslyAllowSignInWithoutUserInCatalog ? { entityRef: { name: localPart } } : undefined, }, ); }; }, });2.3 已接入该配置的提供方模块本版本中以下auth-backend-module-*提供方模块均为-next.2同步引入了dangerouslyAllowSignInWithoutUserInCatalog配置项atlassian-provider、aws-alb-provider、azure-easyauth-provider、bitbucket-provider、bitbucket-server-provider、cloudflare-access-provider、gcp-iap-provider、github-provider、gitlab-provider、google-provider、microsoft-provider、oauth2-provider、oauth2-proxy-provider、oidc-provider、okta-provider、onelogin-provider、vmware-cloud-provider同时backstage/plugin-auth-backend0.25.0-next.2也支持在AuthResolverContext中使用dangerousEntityRefFallback。安全提示该能力冠以 “dangerous” 前缀启用后等同于放宽“用户必须存在于 Catalog 才能登录”的默认约束通常仅适用于目录数据尚未完全同步、或需要先登录后建档的引导场景。请务必结合组织的安全策略决定是否开启。三、Azure DevOps 集成托管身份联合凭据3.1 变更内容backstage/integration1.17.0-next.3为 Azure DevOps 集成新增了对**基于托管身份managed identities的联合凭据federated credentials**的支持。联合凭据仅对已配置使用 Entra IDAzure AD进行认证的 Azure DevOps 组织可用适用于在 Azure 资源如 VM、App Service、AKS上运行、希望免去长期客户端密钥的部署场景。配置示例在app-config.yaml的integrations.azure下为凭据增加managedIdentityClientId与tenantIdintegrations: azure: - host: dev.azure.com credentials: - clientId: ${APP_REGISTRATION_CLIENT_ID} managedIdentityClientId: system-assigned tenantId: ${AZURE_TENANT_ID}3.2 system-assigned 托管身份快捷方式除了指定具体的托管身份外本版本还支持自动使用 Azure 资源的系统分配system-assigned托管身份将凭据的clientId直接写为字符串system-assigned即可integrations: azure: - host: dev.azure.com credentials: - - clientId: ${AZURE_CLIENT_ID} - clientId: system-assigned源码层面ManagedIdentityClientAssertion.ts 中clientId ?? system-assigned的默认值逻辑以及clientId system-assigned的分支判断印证了该快捷方式的实现CachedAzureDevOpsCredentialsProvider.ts 则负责凭据的缓存与刷新。仓库中的单元测试如 ManagedIdentityClientAssertion.test.ts 中的 “Should handle system-assigned managed identity”验证了该路径。使用前提运行 Backstage 后端的主机必须已启用托管身份且该身份需被授予访问 Azure DevOps 相应组织的权限联合凭据授权在 Entra ID 中配置。四、Catalog分页体验优化与全新 Gitea Provider4.1 offset 分页表格的分页栏调整backstage/plugin-catalog1.30.0-next.3调整了启用 offset 分页pagination: offset时CatalogTable的渲染在表格顶部移除重复的分页栏并在底部显示分页文本如“1-20 of 120”。此前顶部与底部会同时出现分页控件造成视觉冗余本次变更统一为仅在底部呈现。该改动纯前端表现层无配置项变更如果你在自定义页面中引用了CatalogTable升级后请检查顶部是否不再显示分页栏。4.2 新增 Gitea Catalog Provider 模块本版本首次发布backstage/plugin-catalog-backend-module-gitea0.1.0-next.0为 Gitea 代码托管平台提供 Catalog Provider 模块支持从 Gitea 实例发现并注册实体。该模块依赖backstage/integration1.17.0-next.3集成配置复用integrations.giteabackstage/plugin-catalog-node1.17.0-next.2Provider 与实体处理基础设施backstage/backend-plugin-api1.3.1-next.2新后端系统插件 API启用方式与其它 Catalog Provider 一致在 backend 中以新后端系统方式注册该模块并在app-config.yaml的integrations.gitea中配置实例的host、username与password或 token。同时本版本已有backstage/plugin-catalog-backend-module-gitea0.2.9-next.3用于 Scaffolder 的 Gitea 操作二者定位不同前者面向目录发现后者面向模板动作。4.3 其它 Catalog 相关更新backstage/plugin-catalog-backend-module-github0.9.0-next.3新增“包含已归档仓库”的过滤选项ee9f59f便于归档仓库纳入或排除目录发现范围。backstage/plugin-catalog-backend2.0.0-next.3补充说明entity-fetch审计事件默认不写入日志仅当日志严重级别被调高时才显示8e0f15f便于排查审计日志“缺失”的困惑。五、URL 读取GithubUrlReader 支持完整 glob 语法backstage/backend-defaults0.10.0-next.3将GithubUrlReader的search方法对 glob 模式的识别从“仅检测*和?字符”升级为使用minimatch完整解析。现在可以搜索诸如{C,c}atalog-info.yaml大小写分支、**、[]字符集等模式// 现在支持的模式示例源自变更说明 const results await reader.search(https://github.com/org/repo/blob/{C,c}atalog-info.yaml);从源码 GithubUrlReader.ts 可见其引入了Minimatchimport { Minimatch } from minimatch并用于search()的模式匹配。这一改动统一了 GitHub 与仓库内其它 URL 读取器Azure、Bitbucket、Gerrit 等同样使用 minimatch的 glob 语义避免了此前复杂模式被当作字面量处理而搜不到结果的问题。六、搜索Elasticsearch queryOptions 配置修复与 i18n6.1 search.elasticsearch.queryOptions 生效backstage/plugin-search-backend-module-elasticsearch1.7.2-next.3修复了一个配置问题此前search.elasticsearch.queryOptions中的配置未被ElasticSearchSearchEngine读取导致模糊匹配、前缀长度等查询参数无法按预期工作。从源码 ElasticSearchSearchEngine.ts 可以看到修复后的读取路径this.queryOptions config.getOptional(search.elasticsearch.queryOptions) ? config.getConfig(search.elasticsearch.queryOptions).getElasticSearchQueryConfig() : undefined;并在构建查询时应用fuzziness默认auto与prefixLength默认0等参数。示例配置search: elasticsearch: provider: elastic queryOptions: fuzziness: auto prefixLength: 06.2 搜索插件 i18n 支持backstage/plugin-search1.4.26-next.3与backstage/plugin-search-react1.9.0-next.2新增了国际化i18n支持fa48594同时search-react修复了SearchFilter.Autocomplete中filterValue的 memoization 问题2c76614避免筛选值意外重置。七、Scaffolder任务重试刷新 token 与参数解析健壮性backstage/plugin-scaffolder-backend1.33.0-next.3与backstage/plugin-scaffolder-node0.8.2-next.3包含两项值得关注的行为变化每次任务重试生成新 tokenec42f8e当 Scaffolder 任务执行失败并重试时会为任务重新生成凭据 token避免复用可能已过期或已吊销的旧 token提升重试任务在受管环境如 GitHub/GitLab 集成中的成功率。parseRepoUrl 参数斜杠裁剪16e2e9cparseRepoUrl解析的查询参数现在会修剪首尾斜杠避免ownerfoo/这类带多余斜杠的输入导致仓库路径解析异常。前端侧backstage/plugin-scaffolder1.31.0-next.3将自定义字段迁移到新的 schema 工厂函数并统一字段描述优先使用ui:description的呈现方式a274e0a若你维护了自定义字段扩展升级后建议同步迁移到新工厂并检查描述渲染。八、CLI 与前端系统构建体验与扩展配置容错8.1 CLIrspack 启用 lazyCompilation 与 refreshOptionsbackstage/cli0.32.1-next.3修复并启用了 rspack 构建链路下的lazyCompilation与refreshOptions674def9。lazyCompilation按需编译模块可显著降低大型应用开发时的启动与热更新开销refreshOptions则涉及 React Fast Refresh 的配置。此项对使用 rspack 作为构建后端的用户影响最为直接无需手动配置即默认开启。8.2 前端应用允许忽略未知扩展配置backstage/frontend-app-api0.11.2-next.3为createSpecializedApp增加了allowUnknownExtensionConfig标志。通过传入{ flags: { allowUnknownExtensionConfig: true } }当应用的扩展配置中包含当前未加载扩展的未知配置项时不再报错而是静默忽略。这在“同一份配置被不同裁剪版应用复用”的场景下可避免配置校验失败createSpecializedApp({ features: [...], config, flags: { allowUnknownExtensionConfig: true }, });注意该开关会掩盖配置拼写错误生产环境建议保持默认关闭。8.3 release-manifests 的受限网络支持backstage/release-manifests0.0.13-next.0扩展了配置能力163f3da允许在跨版本升级时指定镜像mirrored、代理proxied或隔离air-gapped主机服务于大型企业与政府机构等受限或强管控的开发环境为后续 CLI 的更多配置选项铺路。九、Notifications邮件 SES 端点与 Slack 提及替换邮件模块backstage/plugin-notifications-backend-module-email0.3.9-next.3支持配置 SES 连接端点aa3a63a便于本地测试或使用替代邮件堆栈时指向自定义端点。Slack 模块backstage/plugin-notifications-backend-module-slack0.1.1-next.3修复了 dataloader 缓存并改用正确的 catalog 服务引用f6480c7同时通知内容中引用的用户实体引用entity ref现在会被替换为 Slack 兼容的提及格式e099d0aWelcome user:default/billy! - Welcome U123456890!十、Home 插件与 UI 细节更新backstage/plugin-home0.8.8-next.3HomePageRecentlyVisited与HomePageTopVisited接入 Catalog presentation APIf7ca0fecustomHomePageGrid新增可选titlepropeddd96c从backstage/plugin-home-react导出ContentModal并将CatalogReactComponentsNameToClassKey更名为PluginHomeComponentsNameToClassKey16eb4bf若你引用了旧名称需同步修改QuickStartCard的docsLinkTitle支持任意React.JSX.Element并新增additionalContentprop可逐步替代videoprop导出 home 插件根页面路由便于从插件外部添加导航链接195323f更新preventCollisionprop 的默认值文档说明d710d74。backstage/canon0.4.0-next.3修正 TextField 清除按钮的颜色 token避免图标显隐时的布局抖动并修复与前置图标共存时的收缩问题c8f32db。十一、升级注意事项与验证建议明确预发布属性v1.39.0-next.3的所有包版本均为-next.*预发布跨版本升级时应通过官方 Upgrade Helper 工具核对依赖矩阵正式环境请等待稳定版发布。自定义 OAuth2 连接器若你计划启用自定义AuthConnector务必保证内部 scope 变换与OAuth2CreateOptions#scopeTransform完全一致并参考 OAuth2CustomAuthConnector.test.ts 建立同等覆盖的测试。登录回退开关dangerouslyAllowSignInWithoutUserInCatalog涉及安全边界默认应关闭仅在目录数据未同步等受控场景按提供方模块逐个开启。Azure 联合凭据确认 Azure DevOps 组织已启用 Entra ID 认证且运行环境已正确配置托管身份system-assigned快捷方式要求资源本身启用了系统分配托管身份。行为变化点Catalog 表格顶部不再显示分页栏、GithubUrlReader.search的 glob 语义变更、Scaffolder 重试刷新 token、parseRepoUrl斜杠裁剪均可能影响现有页面表现或脚本行为建议纳入回归测试范围。通过上述逐项梳理可以看到v1.39.0-next.3的核心方向是认证链路的可定制化与容错性、云集成Azure/Gitea的增强以及开发体验rspack 编译、搜索配置的持续打磨。结合本文给出的源码路径与配置示例你可以按模块评估变更影响并提前完成对应的配置与代码调整。【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
