NiFi 的权限模型不是 RBAC:users.xml、authorizers.xml 与组件级策略
这是「NiFi 生产集群」系列的第 3 篇。
上一篇:NiFi 从 3 台扩到 25 台 本篇:用户、组、策略到底怎么落 下一篇:FTP→HDFS 与 CSV→Parquet 的完整流程
1. 先纠正一个直觉:NiFi 没有"角色"
大多数平台给权限的方式是 RBAC:建角色 → 角色绑资源 → 用户绑角色。NiFi 不是。
NiFi 的授权是 "主体(用户/组)→ 策略(资源 + 动作)" 的直接映射:
User/Group ──► Policy(resource="/data/processor/<uuid>", action="R"/"W")
没有中间层,没有继承角色的概念。所谓"继承",是资源路径的父子继承(父进程组的策略自动作用于子组件),跟角色无关。
这个模型的好处是细:可以精确到"张三能看这个处理器的数据、但不能改它的配置";坏处是:新建的用户默认什么权限都没有,连登录进去都是一片空白。
2. 三个文件的分工
开了安全之后,conf/ 下有三个文件在管这件事,很多人把它们搞混:
| 文件 | 存什么 | 谁写 |
|---|---|---|
authorizers.xml | 授权器怎么搭:用哪个 UserGroupProvider、哪个 AccessPolicyProvider、初始管理员是谁、节点身份是谁 | 运维手工写,改完要重启 |
users.xml | 有哪些用户和组(只有身份字符串) | NiFi 启动时生成,UI 里增删 |
authorizations.xml | 有哪些策略(资源 + 动作 + 绑定的用户/组) | UI 里改,NiFi 自动写 |
三者关系:
ERROR: [Mermaid] Parse error on line 1:
flowchart LR A[aut
^
Expecting 'NEWLINE', 'SPACE', 'GRAPH', got 'ALPHA'
authorizers.xml 的第一种写法是老式的 FileAuthorizer,第二种是新式的 StandardManagedAuthorizer(由 FileUserGroupProvider + FileAccessPolicyProvider 组合)。NiFi 1.17 两种都支持,行为差别不大,但新集群建议用后者,因为 users.xml/authorizations.xml 的读写更规范,后面换 LDAP 也只需要换 provider。
老式写法(我们生产用的就是它,简单直接):
<authorizer>
<identifier>file-provider</identifier>
<class>org.apache.nifi.authorization.FileAuthorizer</class>
<property name="Authorizations File">./conf/authorizations.xml</property>
<property name="Users File">./conf/users.xml</property>
<property name="Initial Admin Identity">nifi@EXAMPLE.COM</property>
<property name="Node Identity 1">CN=nifi-node-01.example.com, OU=NIFI</property>
<!-- ... 其余节点 -->
</authorizer>
新式写法:
<authorizers>
<userGroupProvider>
<identifier>file-user-group-provider</identifier>
<class>org.apache.nifi.authorization.FileUserGroupProvider</class>
<property name="Users File">./conf/users.xml</property>
<property name="Initial User Identity 1">nifi@EXAMPLE.COM</property>
</userGroupProvider>
<accessPolicyProvider>
<identifier>file-access-policy-provider</identifier>
<class>org.apache.nifi.authorization.FileAccessPolicyProvider</class>
<property name="User Group Provider">file-user-group-provider</property>
<property name="Authorizations File">./conf/authorizations.xml</property>
<property name="Initial Admin Identity">nifi@EXAMPLE.COM</property>
<property name="Node Identity 1">CN=nifi-node-01.example.com, OU=NIFI</property>
</accessPolicyProvider>
<authorizer>
<identifier>managed-authorizer</identifier>
<class>org.apache.nifi.authorization.StandardManagedAuthorizer</class>
<property name="Access Policy Provider">file-access-policy-provider</property>
</authorizer>
</authorizers>
3. 全局策略:11 个开关,决定"这个人能不能干活"
全局策略管的是系统级能力。UI 里在空白画布右键 → Policies,或者右上角菜单 → Policies。
3.1 11 个全局策略一览
| 策略 | 资源描述符 | 作用 |
|---|---|---|
| view the user interface | /flow | 能看见 UI(没有它登录后一片空白) |
| access the controller | /controller | 看/改控制器设置、报告任务、参数上下文、集群节点 |
| access parameter contexts | /parameter-contexts | 参数上下文 |
| query provenance | /provenance | 查数据来源 |
| access restricted components | /restricted-components | 创建/修改受限组件(见第 5 节) |
| access all policies | /policies | 看/改所有组件的策略 |
| access users/user groups | /tenants | 管理用户和组 |
| retrieve site-to-site details | /site-to-site | 允许别的 NiFi 实例拉 S2S 详情 |
| view system diagnostics | /system | 看系统诊断 |
| proxy user requests | /proxy | 代理其他用户发请求 |
| access counters | /counters | 看/改计数器 |
3.2 四类人的最小授权组合
实践中的最小授权组合:
- 普通业务用户:
/flow+ 自己流程组的view/modify。 - 流程开发:上面 +
/controller(要建 Controller Service)+/provenance。 - 运维:再加
/tenants、/policies、/system、/counters。 - 管理员:全给。
3.3 授过头的三项:/tenants、/policies、/controller
| 策略 | 授给业务组之后会发生什么 | 建议 |
|---|---|---|
/tenants | 他能建用户、改组,等于能给自己加权限 | 只给运维 |
/policies | 他能改任意组件的策略,等于能提权 | 只给运维 |
/controller | 他能看到所有 Controller Service 的连接串、报告任务、集群节点 | 开发按需,业务不给 |
/tenants 和 /policies 本质是"发权限的权力"。给了这两项,就等于给了管理员,只是少几个菜单入口而已。
3.4 全局策略的变更要留痕
全局策略在 UI 上点一下就生效,事后没有 diff 可看:谁改的、改了哪一项,只能去翻 nifi-user.log。我们的做法是每改一次就在变更单里写一行——谁 / 给哪个组 / 加了哪一项 / 为什么。全局策略的影响面是"整个 NiFi",不是一条流程,这一行记录在半年后是救命的。
3.5 坑:Initial Admin 不等于根组权限
坑:
Initial Admin Identity只是把"管理用户和策略"的入口给到了你,根进程组的 view/modify 策略并不自动给你。所以新集群配好后,管理员第一次进 UI 会发现连画布都动不了,需要自己给自己授一次根组的view the component+modify the component。
3.6 初始管理员不生效:Unable to locate initial admin
现象:全新集群第一次起,Kerberos 认证能过,UI 也能打开,但进去一片空白,没有任何权限;nifi-app.log 里只有这么一行,后面跟一段堆栈:
org.apache.nifi.authorization.AuthorizationException: Unable to locate initial admin <identity> to seed policies
这行报错里的 <identity> 是实际打印的值,不是你配置文件里以为的值。它就是排查的全部线索——NiFi 拿着这个字符串去 UserGroupProvider 里找人,没找到,seed 就失败了。
三种触发,我们三种都踩过:
| 触发 | 具体表现 | 怎么确认 |
|---|---|---|
authorizers.xml 里 Initial Admin Identity 为空或拼错 | 属性值留空、结尾多一个空格、复制粘贴时混进全角空格 | 把值整行复制出来,cat -A 看行尾有没有多余空白 |
| 写的身份和实际登录身份不一致 | Kerberos 主体大小写不同、realm 后缀不同、前缀不同(etl_admin vs admin) | 先 klist 看真实 principal,再和配置逐字符比对 |
已经 seed 过一次,但 users.xml 里没有这个用户 | 换了管理员、删了旧用户,改 authorizers.xml 后依旧报同一行 | 看 users.xml 里有没有这个 identity |
第二条是最常见的。NiFi 是拿认证通过的 principal 字符串去 users.xml 里逐字符匹配的:etl_user_01、etl_user_01@EXAMPLE.COM、ETL_USER_01 在 NiFi 眼里是三个不同的人;前缀不同(etl_user_01 与 etl_user_01_admin)也一样。Kerberos 侧改了 realm 大小写、或者从 user@EXAMPLE.COM 换成了带前缀的 etl/user@EXAMPLE.COM,NiFi 这边就得跟着改,否则就是"能认证通过、但没有权限"。
两种写法的对应属性,这是最容易漏的地方:
| 写法 | 必须写的属性 | 少写一个会怎样 |
|---|---|---|
老式 FileAuthorizer | Initial Admin Identity(在 authorizer 里) | 缺了或拼错,直接报上面那行 |
新式 StandardManagedAuthorizer | Initial User Identity 1(在 userGroupProvider 里)和 Initial Admin Identity(在 accessPolicyProvider 里) | 只写后者:用户列表里没有这个人,同样报 Unable to locate initial admin;只写前者:人是建出来了,但没有任何策略种子,管理员进 UI 一片空白 |
正确的新式写法(nifi@EXAMPLE.COM 换成你的管理员主体):
<authorizers>
<userGroupProvider>
<identifier>file-user-group-provider</identifier>
<class>org.apache.nifi.authorization.FileUserGroupProvider</class>
<property name="Users File">./conf/users.xml</property>
<property name="Initial User Identity 1">nifi@EXAMPLE.COM</property>
</userGroupProvider>
<accessPolicyProvider>
<identifier>file-access-policy-provider</identifier>
<class>org.apache.nifi.authorization.FileAccessPolicyProvider</class>
<property name="User Group Provider">file-user-group-provider</property>
<property name="Authorizations File">./conf/authorizations.xml</property>
<property name="Initial Admin Identity">nifi@EXAMPLE.COM</property>
<property name="Node Identity 1">CN=nifi-node-01.example.com, OU=NIFI</property>
</accessPolicyProvider>
<authorizer>
<identifier>managed-authorizer</identifier>
<class>org.apache.nifi.authorization.StandardManagedAuthorizer</class>
<property name="Access Policy Provider">file-access-policy-provider</property>
</authorizer>
</authorizers>
两处引号里的字符串必须逐字符相同,也必须和 Kerberos 登录后的 principal 逐字符相同。差一个字符,前面那行报错就会再出现一次。
seed 只发生一次,这是这个坑最反直觉的地方:
- NiFi 首次启动时,如果
users.xml/authorizations.xml不存在,就用Initial Admin Identity建一个用户、写一份根组策略,落盘; - 这两个文件一旦生成,之后无论怎么改
authorizers.xml都不会重新 seed,改完重启也没用; - 要重来:停整个集群 → 备份
conf/→ 两个文件一起删 → 只启一台,等它重新生成 → 把这个节点的两个文件分发到其余节点 → 再启其余节点。顺序不能反,否则 25 台各 seed 各的,最后还得对齐; - 不要只删一个。只删
authorizations.xml会留下策略里引用的用户不存在的状态;只删users.xml则策略全成孤儿; - 不想重来(生产上通常不想):用当前还能登录的管理员在 UI 里手工把人补上、把策略补上,改
authorizers.xml那一步留着下次重建时再做。
一句经验:这行报错虽然出现在"授权"里,但跟 KDC、跟 keytab、跟票据都没关系,根因永远在"身份字符串对不上"。别一上来就查 Kerberos。
4. 组件级策略:细到单个处理器
组件级策略管的是画布上的对象(进程组、处理器、输入/输出端口、控制器服务、参数上下文)。一共 10 个:
4.1 10 个组件级策略
| 策略 | 资源 + 动作 | 能干什么 |
|---|---|---|
| view the component | /<type>/<uuid> R | 看配置详情 |
| modify the component | /<type>/<uuid> W | 改配置、连线、移动 |
| operate the component | /operation/<type>/<uuid> W | 启动/停止/启用/禁用、终止线程 |
| view provenance | /provenance-data/<type>/<uuid> R | 看该组件产生的出处事件 |
| view the data | /data/<type>/<uuid> R | 看队列里的 FlowFile 内容与元数据 |
| modify the data | /data/<type>/<uuid> W | 清空队列、重放 |
| view policies | /policies/<type>/<uuid> R | 看谁能操作它 |
| modify policies | /policies/<type>/<uuid> W | 改谁能操作它 |
| receive via S2S | /data-transfer/input-ports/<uuid> W | 端口收数 |
| send via S2S | /data-transfer/output-ports/<uuid> W | 端口发数 |
4.2 两条容易忽略的规则
- 想编辑一个处理器,必须同时有
view和modify。只给modify,用户能移动它,但打不开配置面板。 - 连线(Connection)没有独立策略,它由"源组件的策略 + 目标组件的策略 + 所在进程组的策略"共同推断。所以"用户能连线"这件事,光给目标组件授权是不够的。
4.3 <type> 到底有哪些值
看 authorizations.xml 或者调 API 时,资源描述符里的 <type> 是固定几个字符串,不是组件类名:
<type> | 对应对象 |
|---|---|
process-groups | 进程组(画布上的方框) |
processors | 处理器 |
input-ports / output-ports | 输入 / 输出端口 |
controller-services | 控制器服务 |
parameter-contexts | 参数上下文 |
reporting-tasks | 报告任务 |
funnels / labels | 漏斗、标签(一般跟随进程组,不单独授) |
排查时容易搞错的是 operate:它的资源不是 /processors/<uuid>,而是 /operation/processors/<uuid>,动作是 W。找策略找不到时先看这一点。
4.4 五个授权入口,别在错的地方点
| 想授什么 | 从哪进 |
|---|---|
| 全局能力(11 项) | 空白画布右键 → Policies,或右上角菜单 → Policies |
| 进程组 | 进程组右键 → Manage access policies |
| 处理器 / 端口 | 组件右键 → Manage access policies |
| 控制器服务 | Controller Services 列表 → 行尾菜单 → Access policies |
| 参数上下文 | Parameter Contexts 列表 → 行尾菜单 |
在处理器上点开 Policies 看到的是"这个处理器自己的策略",不是它所在进程组的。这是"明明授了却还是不行"的又一个来源——你授在了组上,但组件上有一份 Override。
4.5 用 API 反查一个组件被谁授权
UI 里一个个点太慢,直接用 Policies 接口:
curl -k --negotiate -u : \
'https://nifi-node-01.example.com:8443/nifi-api/policies/read/processors/<uuid>'
返回里 users 和 groups 两个数组就是"谁能看这个处理器"。要查 operate 就把资源换成 operation/processors/<uuid>、动作用 write。批量核查一批流程的授权时,这比截图问人快得多。
4.6 组件被 disable:看着像权限,其实是状态
现象:业务反馈 biz_a_FTP接入 下游那条 PutParquet 流程"不执行",队列持续积压。第一反应是权限——查了,用户对这个进程组 view、modify、operate、view the data 全套都有,UI 上看得见、点得动,策略页一切正常。
证据:队列里的 FlowFile 数量只涨不降,处理器图标是灰的、带一个警示标记;打开处理器配置,Validation 栏写着依赖的 Controller Service 不可用;nifi-app.log 里对应的是:
Controller Service ... is disabled
根因:这条流程依赖的 Controller Service(CSVReader、AvroSchemaRegistry 这类)在某次变更/升级之后被置成了 DISABLED,状态没回来。NiFi 的规则很硬:依赖的服务不是 ENABLED,处理器就永远不被调度——它不报错、不进 failure 队列、也没有明显的失败日志,只是不动。所以从外面看像"没权限",实际是"没开工"。
权限问题和状态问题怎么一眼分开:
| 维度 | 权限问题 | 状态问题(DISABLED) |
|---|---|---|
| 用户看到什么 | 提示 not authorized、进程组不可见、双击弹无权限 | 组件可见、可点,但灰显或带警示图标 |
| 队列 | 不受影响,数据该动还在动 | 上游继续写,下游不消费,数字只涨不降 |
| 日志 | nifi-user.log 里只有 debug 级别的授权拒绝 | Controller Service ... is disabled、处理器 invalid |
| 策略页 | 确实没给,或者被 Override 断链 | 齐全,给了也没用 |
| 处置 | 补策略 | Enable 服务 + Restart 处理器 |
处置顺序(照着做,别跳步):
- 进程组右键 → Configure → Controller Services,或者画布右上角的 Controller Services 列表;
- 按
State排序,找DISABLED的那些; - 右键 → Enable,等
State变成ENABLED、Validation变成VALID(有校验错误时先修配置,Enabled 了也是INVALID); - 回到画布,对提示
Restart required的处理器右键 Restart(不是 Start——已经在跑但状态 invalid 的处理器,只有 Restart 会重新走@OnScheduled); - 看队列是否开始消化。还不消化,再查背压、上游调度、磁盘。
这一套做完通常 10 秒。但当时我们按"权限"方向查了半天,因为现象太像了:队列堆积 + 业务说"跑不了"。
预防:
- 把"一个进程组里所有 Controller Service 的状态"做成巡检项:UI 里按 State 排序看一遍,或者调
nifi-api/flow/process-groups/<pgid>,返回的controllerServices里带状态; - 任何变更(升级、改
nifi.properties、重签证书、重启)之后,先把 CS 的 State 扫一遍再交付; - 记一句:NiFi 里"能看能点但不干活",先看状态再看权限。 反过来说,权限不足时你连"不干活"都看不见——这才是两者的分水岭。
5. 受限组件:不是权限,是"能力开关"
有一类处理器天生危险:能执行 shell(ExecuteStreamCommand)、能读写本地文件系统(GetFile/PutFile)、能读 keytab、能读环境凭证、能写 HDFS。
NiFi 把它们标成 Restricted Component,并且在创建/修改时要求用户额外具备 /restricted-components 策略,且要声明具体需要哪一种能力:
| 能力 | 典型组件 |
|---|---|
| 需要执行代码 | ExecuteStreamCommand、ExecuteScript |
| 需要读写本地文件系统 | GetFile、PutFile、ListFile |
| 需要读写分布式文件系统 | PutHDFS、GetHDFS、ListHDFS |
| 需要访问环境凭证 | 各类需要读环境变量的处理器 |
| 需要访问密钥表(keytab) | 所有 Kerberos 处理器 |
| 需要访问票证缓存 | 依赖 ticket cache 的处理器 |
| 需要导出 NiFi 详细信息 | 诊断类组件 |
实际配置时,在"access restricted components"策略里可以只授权某几种限制,也可以"不受限制"。生产上不建议给"不受限制" ——那等于把 shell 执行权也一起给了。
我们的做法:/restricted-components 只授给两个运维账号,业务用户组一律不给;ExecuteStreamCommand 这类组件由运维建好、把策略授给业务组,业务组只有 operate 权限,改不了配置。
6. 一次完整的"加人"操作
以新增业务用户 etl_user_01 为例。
6.1 先建 Kerberos 主体
kadmin.local -q "addprinc -pw '<ADMIN_PASS>' etl_user_01@EXAMPLE.COM"
# 注意:一定要设密码,Kerberos 登录页要输密码;-randkey 会导致 UI 登不进去
6.2 在 UI 里建同名用户
右上角 → Users → 添加用户 → Identity 填 etl_user_01@EXAMPLE.COM(和 Kerberos 主体完全一致,大小写、realm 都不能差)。
"完全一致"是硬要求,因为 NiFi 拿 Kerberos 认证通过的 principal 字符串去 users.xml 里匹配,差一个字符就是"未授权用户"。
6.3 建组并把人放进去
按业务域建组,例如 grp_biz_a,把 etl_user_01 加进去。以后授权只授组,不授人,人员变动只改组。
6.4 给流程组授权
选中业务方的进程组 → 右键 → Manage access policies:
| 策略 | 授予 |
|---|---|
| view the component | grp_biz_a |
| modify the component | grp_biz_a |
| operate the component | grp_biz_a |
| view the data | grp_biz_a |
| view provenance | grp_biz_a |
如果这个组里要建 PutHDFS,还得单独给 grp_biz_a 授 /restricted-components 的"写分布式文件系统"限制。
6.5 验证"互相看不见"
这是最重要的一步。用 etl_user_01 登录,应该:
- 能看到根画布;
- 只能看到被授权的那个进程组;
- 进不去别的业务组(双击提示无权限);
- 在别的组里搜不到组件。
如果能看到别人的组,说明某个父级策略授大了——NiFi 的策略是向下继承的,根组一旦给了 view,所有子组全可见。
7. 策略继承与覆盖:最常见的"为什么他还是看不到"
规则只有两条:
- 子资源默认继承父资源的策略(父进程组的策略自动作用于组内所有组件)。
- 一旦在子资源上点 Override,继承链就断了,子资源只认自己那份策略,父级后续的变更不再生效。
所以典型故障是:
- 管理员在根组给
grp_biz_a授了view,业务能看见所有组; - 管理员想让 A 组只看见自己的组,于是在 A 组上 Override,但只加了
modify没加view; - 结果 A 组用户能改但看不见,或者干脆什么都看不见。
排查方法:选中组件 → Manage access policies → 看策略上方的提示是 "inherited from ..." 还是 "overridden"。override 之后要自己把 view/modify 都补齐。
8. users.xml / authorizations.xml 的运维注意
这两个文件是 NiFi 的"数据库",手工改的风险很高:
- 改之前先备份,并且停节点再改。运行中手改,NiFi 下次写盘会把你的改动覆盖掉。
- 集群模式下
users.xml和authorizations.xml所有节点必须一致。UI 操作会自动同步,手工改就必须逐台分发。 - 节点身份(
Node Identity)也在这套体系里。扩容换证书后,旧 DN 的记录要清掉,否则会出现"节点在、但连不上"的怪状态。
8.1 属主:这两个文件必须是 nifi:nifi
内容对、属主错,是这一类问题里最费时间的一种。有人用 root 手工改过、或者 scp 时没指定属主,文件变成 root:root,NiFi 进程就写不进去。
| 现象 | 先看哪里 | 真实原因 |
|---|---|---|
| 策略改了不生效,重启后回滚 | conf/users.xml、conf/authorizations.xml 的属主与权限 | 文件是 root:root,NiFi 能读不能写,改动只在内存里 |
节点起不来,日志开头就是 AuthorizationException / 读文件失败 | conf/authorizers.xml | NiFi 用户读不到配置 |
| 一个节点策略和别的节点不一致,怎么改都不同步 | 该节点 conf/ 整目录属主 | 写盘失败,同步轮不到它 |
处置就一句:停节点 → chown -R nifi:nifi /opt/nifi/conf → 起节点 → 再改一次策略验证能落盘。
ls -l /opt/nifi/conf/users.xml /opt/nifi/conf/authorizations.xml
# 必须是 -rw-r--r-- 1 nifi nifi
chown -R nifi:nifi /opt/nifi/conf
8.2 root 启动过一两次,会留下满地 root 属主的目录
比 conf/ 更隐蔽的是数据目录。装完包随手用 root 起了一次、或者某次排障 sudo 起了一次,content_repository、provenance_repository、logs、work、state 就都成了 root:root。
后面这些目录会以完全不同的面目爆出来:
- 队列卡死:写 content 失败,处理器反复 penalize 重试,队列数字不动,日志里是磁盘/IO 相关的错;
- 节点掉线:租约、心跳、状态文件更新不了,集群视图里这个节点反复 ACTIVE/DISCONNECTED;
- 日志不写:
logs/nifi-app.log属主错了,出问题时最需要日志,恰恰没有。
这三种表现,第一反应都会去查权限策略、查证书、查网络,但跟它们一点关系都没有。先 ls -l 看一眼属主,能省半天。具体怎么从日志区分,见第 5 篇。
一个快速自检脚本:
# 三件事:用户数、策略数、Node Identity 数,25 台应完全一致
for n in $(seq 1 25); do
h=$(printf 'nifi-node-%02d' "$n")
ssh "$h" "
echo -n 'users: '; grep -c '<user ' /opt/nifi/conf/users.xml
echo -n 'policy:'; grep -c '<policy ' /opt/nifi/conf/authorizations.xml
echo -n 'node: '; grep -c 'Node Identity' /opt/nifi/conf/authorizers.xml
"
done | sort | uniq -c
如果 uniq -c 出现多个分组,说明有不一致,先对齐再动业务。
顺手把属主也一起查了,比内容不一致更常见:
for n in $(seq 1 25); do
h=$(printf 'nifi-node-%02d' "$n")
ssh "$h" "stat -c '%U:%G %n' /opt/nifi/conf/users.xml /opt/nifi/conf/authorizations.xml"
done | sort | uniq -c
# 只应出现一行,且是 nifi:nifi
9. 权限设计的建议
9.1 三层目录结构
踩过一轮之后,我们的目录结构固定成三层:
/ (root)
├── 数据接入域
│ ├── 业务A_FTP接入 ← 一组一策,授权给 grp_biz_a
│ └── 业务B_文件同步 ← grp_biz_b
├── 数据加工域
│ └── CSV转Parquet ← grp_data
└── 公共组件
└── 共享 Controller Service ← 只给 view,不给 modify
三条原则:
- 按业务域分进程组,不做单组件授权(除非确有必要)。组件级权限维护成本极高,业务一变就要改。
- 公共 Controller Service 单独放一个组,只授
view,避免业务方改坏共享连接池。 - 管理员永远走"组" ,不要出现只授权给个人的策略——人一走,流程就没人能维护。
9.2 一个业务一个组:新业务接入四步清单
这条可以直接当 checklist 用,四步,缺一步后面都要返工:
| 步 | 动作 | 命令 / 入口 | 验收 |
|---|---|---|---|
| 1 | 建 Kerberos 主体 | kadmin.local -q "addprinc -pw '<ADMIN_PASS>' etl_user_01@EXAMPLE.COM" | 业务侧 kinit 能拿到票据 |
| 2 | UI 建用户 | 右上角 → Users → 添加,Identity 逐字符一致 | users.xml 里出现该 identity |
| 3 | 建组 | 组名 grp_biz_a,把人加进去 | 组内成员数对,且没有多余的人 |
| 4 | 授策略 | 进程组:view/modify/operate/view the data/view provenance;按需加 /restricted-components 的具体能力 | 用该用户登录,只能看到自己这一个组 |
第 4 步之后的验证一定自己做一遍,别让业务去试——"我登录进去什么都没有"这种反馈,九成是第 2 步 identity 差了个字符。
9.3 组名和进程组名用同一套前缀
组名 grp_biz_a,进程组名 biz_a_FTP接入;组名 grp_biz_b,进程组名 biz_b_文件同步。看起来是小事,出事时差别很大:
- 一条流程卡了,看到进程组名就知道该找哪个组、哪几个人;
- 想确认"这个组到底被授了哪些资源",
users.xml里 grep 到组 id,再拿 id 去authorizations.xml里 grep,两跳就能对上,不用在 UI 里翻;
# 1) 名字 → 组 id
grep -n 'grp_biz_a' /opt/nifi/conf/users.xml
# 2) 组 id → 它被授了哪些资源
grep -n '<group-id>' /opt/nifi/conf/authorizations.xml
- 反过来,看到一个陌生的资源被授权,也能立刻判断是哪个业务组干的。
命名不统一的时候,这两步 grep 都做不了,只能一个个点开策略页看——25 台的规模下,这件事会拖到没人愿意做。
10. 小结
- NiFi 的授权是"主体 → (资源, 动作)"的直接映射,没有角色;
authorizers.xml决定用什么 provider 和初始管理员,users.xml存身份,authorizations.xml存策略;- 全局 11 项 + 组件 10 项,编辑组件必须 view + modify 同时有;
- 受限组件要额外授
/restricted-components,并且只授需要的那几种能力; - 继承会被 Override 打断,这是"授权了却看不见"的第一大原因;
- 集群里这两个 xml 必须全节点一致;
- Initial Admin 的 seed 只发生一次:
users.xml/authorizations.xml一旦生成,改authorizers.xml不再重新 seed,Unable to locate initial admin只能靠删文件重来或 UI 手工补; - 组件 DISABLED 不是权限问题:能看能点但不干活,先查 Controller Service 的 State,再查策略。
下一篇进数据流:怎么把 FTP 上的文件落到 Kerberos 化的 HDFS,以及 CSV 转 Parquet 那条支路为什么要分成两条。
本文操作基于 NiFi 1.17.0 文件型授权,身份、realm、口令均已脱敏。