上线第三周,我被拉进一个会议,业务那边第一句话就是:"为什么同样是采购员,李四的 Fiori 首页能看到新上线的采购申请审批应用,张三就是看不到?"
我第一反应还是老套路:查 PFCG 角色、查 S_TCODE、查 S_SERVICE,折腾了一上午,结论是权限数据都正常。最后翻到 Fiori Launchpad 的角色配置,才发现问题出在Business Catalogs(业务目录)上——张三的角色里压根没有挂对应的目录,应用就算在后端激活了,也不会出现在他的首页上。
这个场景我遇到过不止一次。从 ECC 时代转型到 S/4HANA 的权限顾问,十有八九都会在这个地方栽跟头。原因很简单:Fiori 权限体系和传统 ECC 权限体系的底层逻辑已经变了,不再是你给角色塞几个事务码、配几个授权对象就能搞定的。这篇文章我就从权限视角把 Business Catalogs 这套机制掰开揉碎,讲清楚它到底解决了什么、怎么搭一套能跟着业务演进的角色体系,以及上线之后怎么维护不崩盘。无论你是 SAP Basis、安全顾问、Fiori 开发,还是企业内部负责权限的 IT 管理员,这篇都值得花十分钟看完。
1. 先把语境对齐:Fiori 权限和老 ECC 权限根本不是一回事
1.1 那个"权限正常却看不到应用"的典型场景
先复现一下开头那个案例的完整细节。张三和李四都是采购员,角色都是从同一个模板复制出来的。新上线一个采购申请审批的 Fiori 应用,后端网关服务激活了,目录也发布到了开发系统,测试环境里 QA 也验收通过。可到了生产环境,张三的 launchpad 上新应用的磁贴就是死活不出现。
我当时做的第一步是查 PFCG 角色里的授权对象,S_TCODE、S_SERVICE、S_ICF 全都看了,该有的都有,甚至比李四还多。又让张三重登、清缓存,还是不行。最后对照两个用户分配的 PFCG 角色名称,发现李四的角色是"业务角色"类型,里面挂了一个 Business Catalog;张三的角色是传统"单一角色",里面塞了一堆事务码和授权对象,唯独没有挂目录。
这个案例的教训非常典型:Fiori 应用的可见性和后端服务授权,是通过业务目录传递的,不是靠事务码传递的。你可以在角色里把 S_SERVICE 配得再全,只要角色类型不对、目录没挂上,用户在启动台上就找不到这个应用。
1.2 PFCG 的老办法为什么在这里失灵
传统 ECC 的权限模型,核心是"事务码 + 授权对象"。一个角色里放三五个事务码,再配一组授权对象字段值,用户保存完 profile 就完事。这套模型在 GUI 时代很好用,因为 SAP GUI 的操作入口就是事务码,S_TCODE 控住入口,其他授权对象控住操作范围,边界清晰。
到了 Fiori 时代,应用入口变成了 Launchpad 上的磁贴,操作入口变成了 UI5 组件和 OData 服务。一个 Fiori 应用的访问链路至少有四段:
- 前端加载 UI5 组件;
- 调用后端 OData 服务的元数据请求;
- 调用具体的 OData 实体集方法;
- 后台业务逻辑里涉及的传统授权对象检查(比如采购组织、公司代码)。
如果还按老思路,只给用户配 S_TCODE 或者干脆配一个很大的 S_SERVICE,轻则应用不显示,重则权限过度授权。更麻烦的是,Fiori 应用上线时总要跟着改角色、补授权对象,每加一个新应用就要手工动一次角色,角色越攒越多、越攒越乱,最后变成一团谁都不敢动的"蜘蛛网"。
1.3 Business Catalogs 到底打包了什么
SAP 在 S/4HANA 和 Fiori 体系里推出的Business Catalog(业务目录),本质是做了一个"打包":把一个业务场景相关的应用、它们依赖的 OData 服务、以及服务调用所需的授权默认值,统一装进一个目录里。比如"采购申请审批"这个业务场景,对应一个目录;"供应商主数据查询"对应另一个目录。
权限顾问不需要再关心某个应用底层调用了哪个 OData 服务、需要哪些授权对象,只需要判断一件事:这个用户要不要这个业务场景。要,就把对应的目录挂到他的业务角色上;不要,就不挂。
这样做带来的直接好处是角色可演进:业务变了,目录跟着变;目录变了,角色重新生成一下就好,不用逐条去改授权对象。
我做过一个对比表,可以帮助团队快速理解两者的差异:
| 维度 | 传统 PFCG 角色 | Business Role(基于 Catalog) |
|---|---|---|
| 最小授权单元 | 事务码 + 授权对象 | 业务目录(一组应用 + 服务权限) |
| 应用可见性 | 不负责 | 负责(通过目录、组、空间传递) |
| 后端服务授权 | 手工维护 S_TCODE、S_SERVICE 等 | 目录自带授权默认值,自动带入 |
| 新增一个应用 | 手工改角色并补充授权对象 | 更新目录后重新生成角色 |
| 跨角色复用 | 复用困难,拷贝后容易失控 | 同一目录可挂多个业务角色 |
| 变更影响分析 | 靠人肉排查 | 按目录、角色、用户逐层追踪 |
这个表我建议直接放进项目权限文档第一页。团队里如果有人还是"事务码思维",看一遍基本就能转过弯来。
2. Business Catalog 体系拆解:应用、目录、角色、用户的四层联动
2.1 四层链路和每层的职责
要设计好角色体系,先得把 Business Catalog 相关的对象层次在心里立起来。我把它们分成四层:
- App 层:具体的 Fiori 应用,由 UI5 组件、OData 服务、Intent(语义对象 + 动作)组成。比如一个采购申请的审批应用。
- Catalog 层:业务目录,把同一业务场景的若干 App 收集在一起,并携带它们需要的授权默认值。
- Role 层:业务角色(Business Role),一个业务角色可以挂一个或多个业务目录。角色保存后生成授权 profile。
- User 层:用户通过 SU01 分配业务角色,Launchpad 根据用户拥有的角色渲染可用的磁贴。
这四层是逐级包含的关系:用户拥有角色,角色包含目录,目录包含应用。理解了这个链条,排错思路就清晰了:看不到应用,先看角色有没有挂目录;有目录但点进去报 403,再看目录里的服务授权和后端权限;后端权限也没问题,就开始查数据级别的限制。
我在项目里经常跟同事讲一句话:不要一开始就去翻授权对象,先沿着"用户 -> 角色 -> 目录 -> 应用"这条链路走一遍。80% 的 Fiori 权限问题都出在某一层断掉了。
2.2 Authorization Defaults:目录自带的"默认权限建议"
目录里除了应用清单,还有一层容易被忽略的内容,就是Authorization Defaults(授权默认值)。
这个机制可以类比传统 ECC 里的 SU24:系统为每个事务码预置了一套建议的授权对象值,你在 PFCG 里生成权限数据时,系统会自动把这些建议值带进角色。Business Catalog 干的是同一件事,只不过粒度从"事务码"换成了"应用 + OData 服务"。
当一个业务目录被挂进业务角色并生成 profile 时,目录里预置的 OData 服务授权默认值会自动写入角色。这意味着权限顾问不需要知道某个采购应用到底调用的是/sap/opu/odata/sap/...下的哪个服务,也不需要手工去建 S_SERVICE 授权,目录已经把路铺好了。
但这里有一个必须提醒的坑:默认值不等于全部权限。Catalog 负责的是"服务能不能调",至于调了之后数据能不能看、能看哪些范围,往往还要靠更底层的授权对象和 CDS 数据权限来控制。比如一个采购价格查询应用,Catalog 让它能调用查询服务,但用户能不能看到某个供应商的价格,还要看角色里有没有配置对应的组织级别限制。所以,Catalog 解决的是"入口和通道",业务规则级的安全控制仍然需要你认真做。
2.3 内容目录与引用目录,以及目录版本带来的坑
在 Fiori 的角色配置界面,你会看到同一类目录存在两种用法,一种常被称为"内容目录",另一种是"引用目录"。不同版本、不同文档里的叫法略有差异,判断标准只有一个:这个目录是否承担授权传递。
- 内容目录:真正携带应用和授权默认值,挂到角色里会同时授予应用可见性和后端服务权限。
- 引用目录:只是把应用引用到某个角色或空间里,用于让应用显示出来,但本身不重复携带授权。
这样设计是为了避免同一套应用权限在多个角色里重复维护。比如你把某个应用放在内容目录里授权,又在另一个需要"仅显示应用"的角色里用引用目录把它带上,两者各司其职。
实际项目里更容易踩的坑是目录版本。SAP 发布标准目录更新时,可能把新应用、新服务加进一个你已经用着的标准目录里。但你正在使用的业务角色不会自动获得新增授权,必须重新生成角色的权限数据,新内容才会生效。很多项目上线后业务说"新应用发布了为什么我们没有",排查到最后就是角色没有重新生成、profile 还是旧版本。
2.4 Groups、Spaces、Pages:别把可见性当成权限
我看到太多新人把"用户能在 Launchpad 看到应用"直接等同于"用户有权限",其实这是两个维度。
- Business Group(业务组):负责把应用或者目录分组成不同的 tab,让磁贴按业务场景排列。它只影响显示,不负责授权。
- Space(空间)和 Page(页面):这是新版 Launchpad 推荐的布局方式。空间是顶层容器,页面是空间里的页签,你把自己想要的应用/目录放进去。空间可以通过业务角色分配,也可以由用户在 Launchpad 设计器里自定义。
授权链是"Catalog -> Role -> User",可见性链是"Catalog -> Group/Space/Page -> Role -> User"。两者在业务角色里同时存在,但职责完全分离。
我项目里出现过这样的乌龙:用户权限是好的,后端 OData 也能调通,但就是看不到磁贴,最后发现角色里挂的目录没放进任何 Space,Launchpad 渲染时自然就没有它的位置。所以遇到"看不到"的问题,别急着怀疑权限,先检查空间和页面的分配。
2.5 业务角色与技术角色的组合规则
Business Catalog 体系覆盖的是 Fiori 应用,但现实世界里没有哪个企业是 100% 只用 Fiori 的。大量用户仍然要用 SAP GUI 跑后台事务,比如物料管理的 MD04 查库存/需求、采购的 ME11 维护信息记录、财务月结的一堆事务码。这些老事务不会因为上了 S/4HANA 就消失,它们需要的还是传统 PFCG 授权。
因此,绝大多数项目的标准做法是双轨制:
- 业务角色(Business Role):负责 Fiori 应用的可见性和 OData 服务授权;
- 技术角色(Technical Role):负责 SAP GUI 事务码和传统授权对象。
这两个角色必须分开建、分开管,不要混在一个角色里。混在一起的问题在于演进节奏不一致:Fiori 应用更新快,业务角色可能一个月要动好几次;后台事务权限相对稳定,技术角色半年都不需要碰。一旦混用,每次业务角色变更都要做完整的回归测试,拖累整个变更周期。我见过一个客户把 ME23N 这种事务码挂进业务角色,结果 Fiori 应用升级时连带影响了一堆 GUI 用户,差点造成月结事故。
3. 构建可演进角色体系的落地套路:命名规范、分层设计与实操步骤
3.1 目录分类与命名规范
很多项目输在起跑线上,是因为目录和角色命名没有规范,上线三个月后根本分不清哪个目录是干什么的。我的建议是自上而下先定好规则。
先说目录。SAP 标准目录以SAP_开头,比如财务、物料、销售各模块都有自己的一套。标准目录原则上不修改、不复制改造,直接拿来用。自开发应用或需要裁剪的场景,自定义目录用Y_或Z_开头,推荐格式:
Y_BC_<模块>_<业务场景>_<用途>,例如Y_BC_PUR_INQUIRY采购信息查询目录;Y_BR_<模块>_<岗位>_<层级>,例如Y_BR_PUR_BUYER采购员业务角色;Y_TR_<模块>_<岗位>_<层级>,例如Y_TR_PUR_USER采购后台事务技术角色。
这套命名的价值在权限审计和变更影响分析时才会真正体现。项目上线半年后,安全审计要你列出"拥有采购查询权限的所有用户",你只需要用角色名关键词在 SUIM 里过滤,而不是打开几十个角色挨个看。
3.2 三层角色模型:基础、业务、技术
长期运维下来,我建议把角色体系沉淀成三层,每层职责单一、维护频率不同:
- 基础层:所有登录用户都要有的通用权限,比如基本菜单、当前用户自有数据访问、必要的会话参数。维护频率极低。
- 业务层:按岗位职责组织的业务角色,全部基于 Business Catalog 构建,决定用户在 Fiori 里能做什么。维护频率中等。
- 技术层:按后台事务需求组织的技术角色,只放 SAP GUI 相关的事务码和授权对象。维护频率低。
这样分层的核心逻辑是把"变的"和"不变的"隔离。用户入职、转岗、离职,权限变更主要发生在业务层;系统升级带来的标准目录变化,也只影响业务层。审计的时候可以按层去抽查规则是否合理,不用把几十个角色当成一个整体来审查。
3.3 从零搭建一个业务角色的完整步骤
搭一个基于 Business Catalog 的业务角色,看起来简单,但每一步都有细节。我按常规路径走一遍:
- 创建业务角色。在 PFCG 里新建角色,角色类型选择"业务角色"(Business Role);或者使用 Fiori Launchpad 里的"Maintain Business Roles"管理应用。具体入口不同版本有差异,以你系统为准。
- 维护角色描述和所属业务范围,描述里写清楚这个角色对应的岗位,不要写"临时角色"这种无法判断责任范围的名称。
- 添加业务目录。在 Business Catalog 页签,把需要的标准目录或自定义目录挂进来。这一步的核心是"最小够用":宁可少挂一个目录,让用户真需要时再补,也不要为了省事把整个模块的目录全挂上。
- 如果有数据范围限制,比如采购员只能看自己负责的采购组织,在目录的限制配置里维护组织级别。不同版本限制配置的入口不同,但记住一个原则:限制是加在角色和目录的关联上的,不是加在目录本身上的,否则会影响所有使用这个目录的其他角色。
- 如果该应用还需要额外调用自定义 RFC/BAPI,或者有 Catalog 默认值覆盖不到的后端授权对象,在 Authorizations 页签里手工补充。这一步和传统 PFCG 完全一样,也是很多 Fiori 权限问题出现的地方,别漏了。
- 生成授权 profile。保存角色后执行"生成授权数据",系统才会把目录里的授权默认值落进角色的 profile。很多"挂了目录但没权限"的问题,就是这一步没做。
- 分配用户。SU01 里把业务角色分配给用户,或者用 SU10 批量分配;同时把对应的技术角色(如果有)一起分配。注意业务角色和技术角色要同时给,否则用户可能 Fiori 能看到应用,但跳转后台事务时报权限不足。
- 配置 Space/Page 可见性。把业务角色挂到对应的空间/页面,或者确认空间已经分配给用户。这一步直接决定用户能不能在 Launchpad 上看到磁贴。
- 测试验收。用一个全新的测试用户,只分配这个业务角色和技术角色,登录 Launchpad 跑一遍端到端流程。不要复用你自己的超管账号测试,那测不出来任何问题。
3.4 权限验证闭环:SU53、SUIM 和网关 Error Log
角色搭完了,怎么确认配得对?我习惯用的排错路径是这样的:
- 先用 SU53 查用户最后一个失败的授权检查。如果用户运行 Fiori 应用报权限错误,让他在 GUI 里复现问题(如果有对应后台事务)或在他的用户会话里查看失败对象。SU53 在 Fiori 场景下也适用,它会告诉你缺少的授权对象和字段值。
- 再用 SUIM 做整体分析。比如查用户分配了哪些角色、角色里有哪些授权对象、哪些用户拥有某个事务码,都可以在 SUIM 的报表里覆盖。每周我做权限巡检时,SUIM 是主力工具。
- Fiori 特有的问题,去 SAP Gateway 的 Error Log 里看。如果 OData 请求在网关层被拒,Error Log 会记录具体是哪个服务、哪一步授权失败。很多时候前端报 403,根因在后端某个服务没有对当前用户开放,网关日志比前端报错信息有用得多。
这三个工具配合起来,基本能定位 90% 的 Fiori 权限问题。剩下那 10%,通常出在 CDS 数据权限和 UI 注解层,需要到具体的服务实现里去看。
4. 存量 PFCG 角色迁移到 Business Role 的取舍与顺序
4.1 迁移前先做好三件盘点
老系统一定有大量存量 PFCG 角色,不可能全部推翻重来。迁移之前,我会先做三件盘点:
- 盘点 Fiori 使用范围:哪些岗位真的需要 Fiori 应用,哪些岗位只碰 SAP GUI。只要用 GUI 的岗位,技术角色原样保留,不参与迁移。这个范围收得越窄,迁移风险越低。
- 盘点应用与目录的映射:把当前 Fiori 使用的应用清单拉出来,对照标准目录,确认每个应用该挂哪个目录。这一步可以直接用 Fiori 的应用参考库(App Reference Library)或者团队自建的 Fiori Tracker 维护。
- 盘点存量角色的"孤儿权限":老 PFCG 角色里通常有一堆历史遗留的授权对象,很多已经没人知道当时为什么加。这些权限迁过去没有任何价值,反而是审计风险。迁移前先做瘦身,把无主权限清理掉。
4.2 推荐迁移顺序:从纯 Fiori 岗位开始
迁移顺序我强烈建议"先易后难":
- 第一批迁"纯 Fiori 岗位":这些用户只使用 Launchpad 上的应用,不碰 GUI 事务。角色完全由业务角色构成,不存在双轨制,迁移后回归测试简单。
- 第二批迁"混合岗位":既有 Fiori 应用又有 GUI 需求。这类岗位要拆成业务角色 + 技术角色两个对象,拆的时候注意别把 GUI 事务码塞进业务角色。
- 最后处理复杂岗位:比如财务月结、跨模块流程这种既要用 Fiori 又要用多个 GUI 事务的高级用户。这类用户权限覆盖面大,尽量保持业务角色和技术角色的严格分离,必要时做一次完整的数据级权限梳理。
SAP 为存量角色迁移提供了辅助工具,具体程序名和操作路径请以你当前版本的 Release Note 为准。但我要提前给你泼盆冷水:迁移工具只是把目录相关部分机械地转换,真正决定迁移质量的还是迁移前的权限清理和岗位模型梳理。指望一键迁移不现实,90% 的工作量在准备阶段。
我用过一个笨办法:迁移后把新旧角色的授权对象清单导出来做 diff,逐条复核"多出来的"和"少掉的"。这个办法土,但最可靠。你会在 diff 里发现很多想不到的历史包袱,比如某个角色里居然有 SAP_ALL 子集授权,这种问题早发现早处理,拖到审计就晚了。
4.3 混合模式的边界:谁负责应用权限,谁负责后台事务
迁移完成后,系统里长期存在双轨制。这个时候最容易乱的是"边界"——业务角色和技术角色到底以什么为界?
我的标准很简单:
- 凡是 Fiori 应用的前端可见性、OData 服务调用,一律交给业务角色;
- 凡是 SAP GUI 事务码、旧式授权对象、批处理作业需要的后台权限,一律交给技术角色;
- 遇到两端都涉及的对象,宁可两边各配一次,也不要集中在某一侧。
举个例子:一个 Fiori 应用底层调用了 BAPI 去更新采购订单,这个 BAPI 的调用权限,Catalog 的默认值可能不会覆盖。这时候业务角色里需要补充 BAPI 相关的授权对象。同一段时间里,用户也通过 GUI 的 ME22N 维护采购订单,技术角色里也有对应的 S_TCODE。两边各配各的,互不干扰,审计时也能说清楚每个权限是为哪个入口配的。
5. 上线之后如何让角色体系扛得住业务变化
5.1 目录更新与角色再生成:不做这一步等于白配
上线之后,角色体系真正的考验才刚开始。SAP 标准目录会跟着 Support Package 升级而变化:可能新增一个应用,可能给现有应用增加一个新 OData 服务。目录变了,不代表你的业务角色自动跟进。
我踩过一次很深的坑:S/4HANA 版本升级后,财务团队的新应用已经发布到生产环境,用户却集体无法访问。查了一圈发现,标准目录虽然更新了,但业务角色没有重新生成授权 profile,新应用的 OData 服务授权根本没有进入用户的生效 profile。这种问题在测试环境往往发现不了,因为测试用的角色是升级后新创建的;生产环境里跑的却是升级前创建的角色,profile 还是旧的。
所以我把"目录变更 -> 角色再生成 -> 传输到生产"写进了权限变更 SOP,并且在每次系统升级后安排一次全量核对:把生产环境里所有业务角色的 profile 生成日期和目录版本对照一遍,有出入立即补生成。这个检查不难,但漏掉一次就可能出一次事故。
5.2 传输顺序与多系统一致性
Business Catalog 和业务角色是通过 CTS 传输的在开发系统维护、测试验证、然后传到生产。传输顺序有个容易被忽略的细节:先传目录定义,再传角色,最后传空间和页面。
如果角色先传到了目标系统,而目录还没到,角色里的目录引用就会出现断链,用户在 Launchpad 上看不到任何应用或者角色保存报错。空间和页面又依赖于角色里的目录信息,所以放在最后传。跨系统的顺序错了,轻则重复传一次,重则把生产环境的角色状态搞乱。
另外,多系统一致性不能只靠传输顺序。我建议在 QAS 和 PRD 之间做一个月度角色对比报告,重点检查:相同业务角色在三系统的目录挂接是否一致、profile 生成时间是否一致、关键用户分配的角色清单是否漂移。这些对比用 SUIM 导出来就能做,并不复杂,但能避免"测试没问题,生产有问题"的经典尴尬。
5.3 定期巡检清单与常见治理手段
角色体系越庞大,越需要制度化巡检。我在项目里定的巡检清单是这样的,大家可以参考:
| 巡检项 | 频率 | 工具/方法 |
|---|---|---|
| 用户角色分配与岗位职责是否匹配 | 月度 | SUIM 用户角色分析 |
| 是否存在长期未用角色(僵尸角色) | 月度 | 登录日志 + SUIM 对比 |
| 业务角色的 profile 是否最新 | 系统升级后 | 比对生成日期与目录版本 |
| 目录挂接是否有重复或冲突 | 季度 | 角色 vs 目录导出 diff |
| 高权限用户(SAP_ALL、超级用户)名单 | 季度 | SUIM 用户信息报表 |
| 自定义目录权限是否过度开放 | 季度 | 审核自定义目录的 OData 服务清单 |
巡检不是目的,治理才是。我个人的经验是:权限变更必须走传输,禁止在生产环境直接改角色和目录。这条规则看起来死板,却能挡掉 90% 的权限事故。生产环境直接改权限,改完没有测试、没有留痕、没有回退路径,一旦出问题就是线上故障,而且你连改了什么可能都想不起来。
最后分享一个我坚持了很多年的小习惯:每次给新应用、新目录做完权限配置,都用"全新测试用户 + 仅分配目标角色 + 开启 SU53/网关日志"的方式来验收,而不是拿自己的账号随便点两下就认为没问题。很多看似是 Catalog 配错的问题,根因其实是残留旧 profile、空间没分配、或者缓存没刷新。用干净的测试用户跑一遍主流程,这些问题都会原形毕露。这套方法不算高深,但它帮我避过的雷,比任何一篇官方文档都多。