Nacos 默认认证插件(Default Auth Plugin)深度指南:nacos/ldap 认证、RBAC 权限与 AI 资源可见性管控

发布时间:2026/9/11 12:00:56
Nacos 默认认证插件(Default Auth Plugin)深度指南:nacos/ldap 认证、RBAC 权限与 AI 资源可见性管控 Nacos 默认认证插件Default Auth Plugin深度指南nacos/ldap 认证、RBAC 权限与 AI 资源可见性管控【免费下载链接】nacosan easy-to-use dynamic service discovery, configuration and service management platform for building AI cloud native applications.项目地址: https://gitcode.com/GitHub_Trending/na/nacos本篇指南以 default-auth-plugin-spec.md 为骨架系统讲解 Nacos 内置默认认证插件包nacos与ldap两个插件的框架配置、托管插件配置、身份识别、JWT Token 机制、RBAC 存储模型、v3 认证 API 以及被 AI 资源使用的默认可见性实现。读完本文你将掌握如何通过规范化的nacos.plugin.auth.nacos.*/nacos.plugin.auth.ldap.*配置键启用并加固 Nacos 认证理解登录、鉴权、匿名 AI 访问与显式可见性授权的完整链路并能在升级既有集群时正确执行权限资源列的数据库迁移。一、插件包概述与适用范围默认认证实现包位于 plugin-default-impl/nacos-default-auth-plugin目前提供两个认证插件插件提供能力nacos用户名/密码登录、Token 认证JWT、RBAC 权限管理以及供 AI 资源使用的默认可见性集成ldap基于 LDAP 目录服务的身份认证仅替换身份来源Token、用户/角色存储与授权仍复用auth:nacos的基础设施nacos插件是以下三份规范的服务端实现Auth Plugin Spec认证插件的通用契约AuthPluginServiceSPI、IdentityContext等Auth And Permission Spec认证与权限的共享语义Visibility Plugin Spec可见性插件的通用契约。在 Java 客户端侧与该默认插件配套的是NacosClientAuthServiceImpl实现位于 client-basic/src/main/java/com/alibaba/nacos/client/auth/impl/NacosClientAuthServiceImpl.java负责用户名/密码登录与 Token 携带。而 RAM、OIDC 等内置客户端认证服务属于 Java Client SDK 的认证扩展其规范在 Java SDK Implementation Spec 与 Auth Plugin Spec 中定义不属于本文服务端默认插件实现范畴。重要定位声明默认实现的设计目标是降低可信内网中的误用风险它不是面向敌对公网环境的强认证方案。若需公网暴露必须配合外部安全边界或选用更强的认证插件如 OIDC。二、认证框架级配置Auth Framework Configuration以下配置由认证框架统一消费控制认证模块整体开关、API 作用域、启动期插件选择与服务端身份标识。它们不属于auth:nacos插件自身持有的配置项配置项作用nacos.core.auth.enabled启用通用认证体系与 Open API 认证nacos.core.auth.admin.enabled启用 Admin API 认证nacos.core.auth.console.enabled启用 Console API 认证与默认登录行为nacos.plugin.auth.type启动时选择认证插件默认nacosnacos.core.auth.system.type为其历史别名nacos.core.auth.server.identity.key服务端到服务端server-to-server请求的身份标识 Keynacos.core.auth.server.identity.value服务端到服务端请求的身份标识 Value使用注意插件选择必须重启生效nacos.plugin.auth.type是启动期决策服务端身份标识值必须是部署专属的不能使用默认或共享值否则会形成安全隐患。三、托管插件配置Managed Plugin Configuration本小节对应规范 Managed Plugin Configuration 部分。nacos与ldap两个实现都直接实现PluginConfigSpec注册为可配置插件auth:nacos与auth:ldap并遵循 Nacos Plugin Spec 中定义的 common full-source-map 语义进行运行时与本地更新。3.1auth:nacos插件配置规范前缀为nacos.plugin.auth.nacos.Item keyCanonical 静态键旧静态别名类型生效方式默认值敏感token.secret.keynacos.plugin.auth.nacos.token.secret.keynacos.core.auth.plugin.nacos.token.secret.keyStringRESTART空是token.expire.secondsnacos.plugin.auth.nacos.token.expire.secondsnacos.core.auth.plugin.nacos.token.expire.secondsNumberRUNTIME18000否token.cache.enablenacos.plugin.auth.nacos.token.cache.enablenacos.core.auth.plugin.nacos.token.cache.enableBooleanRUNTIMEfalse否caching.enablednacos.plugin.auth.nacos.caching.enablednacos.core.auth.caching.enabledBooleanRUNTIMEtrue否anonymous.ai.enablednacos.plugin.auth.nacos.anonymous.ai.enablednacos.core.auth.nacos.anonymous.ai.enabledBooleanRUNTIMEfalse否关键约束与运行时语义token.expire.seconds必须大于 0。源码 NacosAuthPluginConfig.java 中的parsePositiveLong会拒绝非正数parseBoolean会拒绝非布尔值只要任一 Nacos API 认证作用域需要 Token 支持token.secret.key就必须是合法的 Base64 编码且解码后至少 32 字节。校验逻辑在NacosAuthPluginConfig.validateTokenSecret它通过构造NacosJwtParser来验证密钥失败时抛出“secret key must be encoded by base64”的IllegalArgumentExceptionToken 密钥必须是部署专属的默认或共享值不安全插件管理 API 会以掩码形式返回该密钥且不能通过运行时更新修改当 canonical 键与旧别名同时存在时canonical 键优先旧别名仍可读以兼容历史配置并在不打印配置值的前提下产生迁移诊断信息插件持有不可变的生效配置快照NacosAuthPluginConfig为 final 类。应用新快照会更新 token 过期时间、token 缓存选择、授权缓存行为与匿名访问开关各消费方不再直接读取 Spring 环境属性。Token 管理器的运行时行为对应 TokenManagerDelegate.javaJWT 解析器由仅重启生效的密钥创建开启token.cache.enable时在同一个基础管理器外层包一层缓存包装器CachedJwtTokenManager关闭时切回基础管理器并清空 Token 缓存修改token.expire.seconds同样会清空包装器缓存使下一次 Token 请求采用新生效的运行时生命周期已发放给客户端的 Token 在签名过期前仍然有效密钥变更会被拒绝applyTokenConfig中检测到lastAppliedConfig与当前配置的密钥不一致时直接抛出“Token secret key change requires restart”。源码证据默认值18000、false、true、空密钥等均定义在 NacosAuthPluginConfig.java 与 AuthConstants.java 中且旧键在AuthConstants中被标注Deprecated并计划于 Nacos 4.0.0 移除。独立部署 Console 的初始化独立部署的 Console 在接收请求前会由 Console 本地的认证初始化器从STATIC DEFAULT层级应用内置auth:nacos配置初始化稳定的TokenManagerDelegate及其具体 Token 管理器所有可配置认证实现都会被应用因为 LDAP 等身份提供方仍要消费auth:nacos拥有的 Token 与授权基础设施只有被选中的实现会收到可选的启动生命周期回调。3.2auth:ldap插件配置规范前缀为nacos.plugin.auth.ldap.Item keyCanonical 静态键旧静态别名类型生效方式默认值敏感urlnacos.plugin.auth.ldap.urlnacos.core.auth.ldap.urlStringRESTARTldap://localhost:389否base-dnnacos.plugin.auth.ldap.base-dnnacos.core.auth.ldap.basedcStringRESTARTdcexample,dcorg否timeoutnacos.plugin.auth.ldap.timeoutnacos.core.auth.ldap.timeoutNumberRESTART3000否user-dnnacos.plugin.auth.ldap.user-dnnacos.core.auth.ldap.userDnStringRESTARTcnadmin,dcexample,dcorg否passwordnacos.plugin.auth.ldap.passwordnacos.core.auth.ldap.passwordStringRESTARTpassword是filter-prefixnacos.plugin.auth.ldap.filter-prefixnacos.core.auth.ldap.filter.prefixStringRESTARTuid否case-sensitivenacos.plugin.auth.ldap.case-sensitivenacos.core.auth.ldap.case.sensitiveBooleanRESTARTtrue否ignore-partial-result-exceptionnacos.plugin.auth.ldap.ignore-partial-result-exceptionnacos.core.auth.ldap.ignore.partial.result.exceptionBooleanRESTARTfalse否约束与语义timeout单位为毫秒且必须大于 0绑定密码会被插件管理 API 掩码首个托管版本中所有 LDAP 字段仅重启生效因此对任一字段的运行时/本地更新新增、修改、删除都会被拒绝canonical 键优先于旧别名历史模板键nacos.core.auth.ldap.userdn无连字符不是受支持的别名——没有生产实现消费过它且其本意的 user-DN 模式语义存在歧义LDAP 插件同样持有不可变生效快照Spring LDAP 上下文与模板的构建会惰性读取该已接受快照LDAP 消费方不会再去读另一套Value属性LDAP 只改变身份认证Token 签名与生命周期、Nacos 用户与角色存储、授权逻辑仍使用auth:nacos配置的基础设施这些共享设置在auth:ldap定义中不重复出现。四、身份识别Identity默认插件接受以下身份输入输入用途Authorization: Bearer ...Token 认证accessToken通过请求参数或请求头进行的 Token 认证usernamepassword登录或直接的用户名/密码认证Server identity key/value服务端到服务端请求的身份标识认证成功后插件用已认证的 Nacos 用户与用户 id 丰富IdentityContext全局管理员状态由用户角色模型推导对应ROLE_ADMIN角色见 AuthConstants.java 的GLOBAL_ADMIN_ROLE。4.1 匿名 AI 访问Anonymous AI Access匿名 AI 访问仅在同时满足以下全部条件时被允许端点将请求标记为允许匿名访问Secured的ALLOW_ANONYMOUStagauth:nacos配置中anonymous.ai.enabled为 true默认插件将该请求接受为内置匿名身份。回退语义严格仅当请求没有显式提供任何默认认证凭据键时才可回退到匿名身份。一旦提供了Authorization、accessToken、username或password即使值是空白也视为显式凭据存在此时若凭据为空白或无效插件必须返回认证失败不得回退为匿名身份。在 HTTP 过滤器层失败的身份/权限结果会转换为带 HTTP 403 的ACCESS_DENIED响应插件层的失败码与消息可能保留在响应详情中。4.2 匿名身份的协调器Reconciler启用匿名访问只是立即开启身份接受随后由后台协调器保证保留的匿名用户与角色存在。对应实现为 AnonymousAccessInitializer.java首次初始化时创建匿名用户与随机密码为__nacos_anonymous_role__角色添加public:*:ai/*的r读权限并最后写入匿名角色绑定作为持久化的完成标记源码常量DEFAULT_ANONYMOUS_PERMISSION_RESOURCE public:*:ai/*、DEFAULT_ANONYMOUS_PERMISSION_ACTION r并发节点使用读后冲突校验仅当期望的持久化状态可被观察到时重复创建才视为成功已存在的匿名角色绑定视为已初始化协调器不会恢复宽泛的默认权限从而保留管理员自定义的匿名权限范围关闭匿名访问会停止身份接受但不会删除保留的用户、角色或权限协调状态只是本地数据库工作的优化不是授权条件当匿名身份没有匹配的角色或权限时常规 RBAC 权限检查仍然会拒绝它。五、默认 Java 客户端认证集成客户端侧集成为NacosClientAuthServiceImpl通过客户端认证 SPI 加载SPI 注册文件见 client-basic/src/main/resources/META-INF/services/com.alibaba.nacos.plugin.auth.spi.client.AbstractClientAuthService。客户端实现身份材料契约NacosClientAuthServiceImplusername、password、accessToken通过默认认证 API 登录携带返回的accessToken并在过期前刷新 Token核心实现细节见 NacosClientAuthServiceImpl.java默认使用/v3/auth/user/login登录 APIToken 刷新窗口随机化generateTokenRefreshWindow在[tokenTtl/15, tokenTtl/10]区间随机生成刷新窗口避免大量客户端同时登录对服务端造成压力存在 60 秒的重登录窗口reLoginWindow 60000毫秒若触发了重登录标记且距上次刷新不足 60 秒则直接返回成功依次尝试 serverList 中的每个服务端进行登录成功后在LoginIdentityContext中保存accessToken该集成不得篡改请求负载它只提供被服务端所选认证插件消费的身份材料。其余客户端认证实现RAM、OIDC作为 Java Client SDK 扩展规范见 Java SDK Implementation Spec并分别有 RAM Auth Plugin Spec 与 OIDC Auth Plugin Spec。5.1 登录响应兼容性Login Response Compatibility/v3/auth/user/login及旧版 v1 登录路由的成功响应保持扁平 Token 对象结构包含accessToken、tokenTtl、globalAdmin、username四个字段不使用ResultT包装——因为已发布的 Java 客户端直接解析这一扁平结构。源码证据见 UserControllerV3.java 的login()方法它构造MapString, Object并放入这四个键直接返回同时把Authorization: Bearer token写入响应头。防用户名枚举设计未知用户名、错误密码或空白凭据必须产生相同的 HTTP 403 状态与相同的通用响应体User not found! Please check user exist or password is right!常量INVALID_CREDENTIALS_MESSAGE定义于 AuthConstants.java不得泄露用户名是否存在未知用户认证不执行密码哈希比对因此任意用户名无法迫使服务端执行 CPU 密集的密码编码器防止被用于拒绝服务/时序探测用户存储或 Token 签发的意外失败属于运维错误不得被转换为凭据失败。六、RBAC 存储模型默认插件持久化三类对象对象含义User用户名与密码身份用户表RoleInfo分配给用户名的角色角色绑定表PermissionInfo分配给角色的资源与动作权限表持久化层接口与实现位于 persistence 目录内嵌存储Derby与外部存储MySQL 等各有独立的*PersistServiceImpl。ROLE_ADMIN是全局管理员角色拥有该角色的用户可访问所有资源与控制台管理操作源码常量GLOBAL_ADMIN_ROLE。管理员引导逻辑见UserControllerV3.createAdminUser当已存在全局管理员时返回 HTTP 409have admin user cannot use it.。6.1 模糊搜索的下划线转义对用户、角色、权限的模糊搜索会把_通配符用反斜杠转义使其按字面匹配。但反斜杠只是部分数据库的默认 LIKE 转义字符因此内嵌存储显式声明ESCAPE \。源码证据见 EmbeddedRolePersistServiceImpl.javaSQL_DERBY_ESCAPE_BACK_SLASH_FOR_LIKE ESCAPE \\ generateLikeArgument将_替换为\\_并把*通配符转换为 SQL 的%。关键规则ESCAPE \子句只限定其紧邻的那一个LIKE谓词因此组合多个模糊过滤条件的查询必须在每个LIKE之后重复该子句该规则适用于资源的每一个模糊入口而不仅是分页搜索控制台自动补全背后的名称搜索findRoleNames、findUserNames必须以与分页搜索相同的方式转义参数保证同一个关键字在两种入口下选中相同的行。七、权限资源格式Permission Resource Format默认资源权限使用如下格式{namespaceId}:{group}:{signType}/{resourceName}示例资源示例配置数据public:DEFAULT_GROUP:config/example.properties命名服务public:DEFAULT_GROUP:naming/com.example.Service控制台用户console/users控制台角色console/roles控制台权限console/permissions可见性权限visibility/public/mcp/example-mcp匹配规则权限资源中可使用*作为通配符group 为空时权限检查使用*作为 group 段资源名为空时资源名段变为*存储资源以:开头时按默认命名空间public解释SPECIFIED类型资源直接使用显式资源字符串存储的动作可以是r、w或rw。此外非管理员角色不得管理控制台用户、角色或权限。八、默认认证 APIDefault Auth APIs默认插件拥有以下 v3 API 家族对应源码 controller 目录 controller/v3路径用途/v3/auth/user用户管理与密码更新/v3/auth/user/login登录与 Token 签发/v3/auth/user/admin当不存在全局管理员时的管理员引导/v3/auth/role角色管理/v3/auth/permission权限管理/v3/auth/visibility显式可见性授权管理管理端点必须由控制台作用域的Secured资源保护例如console/users、console/roles、console/permissions、console/user/password。源码示例UserControllerV3.createUser标注为Secured(resource console/users, action ActionTypes.WRITE, apiType ApiType.ADMIN_API)。登录是刻意公开的管理员引导刻意只暴露于“无管理员”的初始化状态一旦存在全局管理员就必须被拒绝返回 409这些 API 属于 V3 API Surface并须遵循 HTTP Authorization Spec可见性授权 API 是插件自有 API不属于任何领域控制器家族它使用ApiType.ADMIN_API 仅身份认证ONLY_IDENTITYtag并在授权服务内执行资源管理权限校验。源码证据见 VisibilityGrantControllerV3.javaPOST /v3/auth/visibility与DELETE /v3/auth/visibility均标注Secured(resource auth/visibility, action ActionTypes.WRITE, apiType ApiType.ADMIN_API, tags Constants.Tag.ONLY_IDENTITY)。启用认证后只有资源所有者或全局管理员才能为某资源授予或撤销显式可见性访问。九、默认可见性实现Default Visibility Implementation默认可见性实现同样名为nacos当前被 AI 资源使用例如 MCP 服务、Agent、Prompt 等 AI 资源的可见性管控。相关实现位于 visibility 目录核心类是DefaultVisibilityService与DefaultVisibilityGrantService。9.1 默认行为新资源默认PRIVATE除非领域层提供其他作用域全局管理员可读写所有可见性感知资源资源所有者可读写该资源PUBLIC资源可被非所有者读取显式可见性权限可通过认证插件授予访问匿名 AI 读访问只通过匿名 AI 主动启用路径放行被拒绝的读取可上报为“未找到”以隐藏资源存在性被拒绝的写入则上报为“访问被拒绝”。9.2 显式可见性权限资源格式visibility/{namespaceId}/{resourceType}/{resourceName}规范要求把精确的 canonical 资源字符串存入默认 RBAC 的permissions.resource列该列必须支持至少 512 字符避免带命名空间的资源被截断资源匹配是精确且区分大小写的因此默认 MySQL schema 对该列使用utf8mb4_bin排序规则并将permissions表设为ROW_FORMATDYNAMIC以保持既有的(role, resource, action)索引在utf8mb4下仍然有效现有 MySQL 部署在应用升级 SQL 前应检查 MySQL 版本、InnoDB 页大小、行格式与当前permissions表定义先配置兼容的 InnoDB 存储模式使既有UNIQUE(role, resource, action)索引能容纳扩大后的utf8mb4资源列。9.3 数据库升级脚本升级脚本随发布包交付源码位置在各 datasource 插件的src/main/resources/META-INF下打包后进入distribution/conf数据库升级脚本精确 schema 变更MySQLmysql-upgrade-visibility-permission-resource.sqlALTER TABLE permissions ROW_FORMATDYNAMIC, MODIFY COLUMN resource VARCHAR(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;Derbyderby-upgrade-visibility-permission-resource.sqlALTER TABLE permissions ALTER COLUMN resource SET DATA TYPE VARCHAR(512);PostgreSQLpg-upgrade-visibility-permission-resource.sqlALTER TABLE permissions ALTER COLUMN resource TYPE VARCHAR(512);Oracleoracle-upgrade-visibility-permission-resource.sqlALTER TABLE permissions MODIFY (resource VARCHAR2(512 CHAR) NOT NULL);MySQL 脚本内置的预检 SQLSELECT VERSION(); SHOW VARIABLES LIKE innodb_page_size; SHOW VARIABLES LIKE innodb_default_row_format; SHOW CREATE TABLE permissions;升级边界这些脚本只扩大原始 canonical 资源列不得新增仅服务于授权列表的反向索引如permissions(resource, action, role)、roles(role, username)。面向运维人员的完整升级说明见 doc/visibility-permission-resource-upgrade.md其中同样强调存储值除 canonical 资源构造规则外不做翻译、转义、哈希或归一化。9.4 显式可见性授权行为Grant Behavior显式可见性授予通过以下端点管理POST /v3/auth/visibility DELETE /v3/auth/visibility两个端点均以ApiType.ADMIN_API保护。核心行为源码见 DefaultVisibilityGrantService.java读授予存储动作r写或读写授予请求存储动作rw且rw隐含读可见性当列表/搜索查询需要时授权数据复用默认 RBAC 持久化在认证后端存储插件自有内部角色与权限默认实现为每个被授权用户至多创建一个保留内部可见性角色角色名确定、对授权人唯一、且受既有角色名列长度约束资源与动作数据只能存放在挂在该角色下的权限行中不得编码进角色名列表/搜索授权必须从调用者保留可见性角色所挂的实际权限行推导显式资源——只有角色绑定而没有匹配权限行不得授予可见性资源存在性与所有者元数据通过领域提供的可见性资源定位器VisibilityResourceLocator解析认证插件不直接编译期依赖领域持久化类型范围查询必须把基础可见性谓词与显式授权资源组合默认实现从授权服务填充显式授权资源使列表/搜索路径能包含授予调用者的私有资源。AI 列表/搜索路径的要求可见性必须在 count 与分页查询执行之前转换为仓库查询条件从而保证totalCount与可见资源集合一致并避免全量加载到内存再过滤。十、兼容性Compatibility旧版/兼容端点可以为既有客户端保留但新文档与新开发应面向 v3 认证 API及本文定义的插件契约托管插件配置表中的旧静态别名继续受支持新发行模板使用 canonical 键并在注释中标注旧键启动脚本在 canonical 键缺失或为空时会把有效的旧版 Token 密钥迁移到 canonical 键两者同时设置时canonical 值优先迁移过程中绝不打印密钥值。十一、待处理问题Pending Issues规范明确记录了一个已知演进方向ldap插件现在通过PluginConfigSpec拥有其 LDAP 连接与查询配置但仍消费由auth:nacos配置的 Token、用户、角色与授权基础设施。后续重构应把这些共享能力移到显式的 auth-module 服务之后使身份提供方插件不再依赖默认插件拥有这些能力。小结配置一张速查表场景推荐配置开启认证nacos.core.auth.enabledtrue选择插件默认已是nacosnacos.plugin.auth.typenacos重启生效设置 Token 密钥Base64解码 ≥32 字节nacos.plugin.auth.nacos.token.secret.keyBase64重启生效调整 Token 有效期秒默认 18000nacos.plugin.auth.nacos.token.expire.seconds18000运行时生效开启 Token 缓存nacos.plugin.auth.nacos.token.cache.enabletrue运行时生效关闭授权缓存nacos.plugin.auth.nacos.caching.enabledfalse运行时生效启用 AI 匿名读nacos.plugin.auth.nacos.anonymous.ai.enabledtrue运行时生效接入 LDAP配置nacos.plugin.auth.ldap.*八项全部重启生效并保持auth:nacos提供 Token/RBAC 基础设施最后提醒以上所有配置的解析、校验与运行时切换语义均可在 NacosAuthPluginConfig.java、TokenManagerDelegate.java 与 UserControllerV3.java 中直接核对默认插件的单元测试覆盖可参考 plugin-default-impl/nacos-default-auth-plugin/src/test 目录Java 客户端登录链路测试见 NacosClientAuthServiceImplTest.java。【免费下载链接】nacosan easy-to-use dynamic service discovery, configuration and service management platform for building AI cloud native applications.项目地址: https://gitcode.com/GitHub_Trending/na/nacos创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考