跳转到内容
OpenClaw 不踩坑恶意 Skills ,企业需 Skills Registry:Nacos 3.2 发布点此了解

鉴权插件

Nacos 从 2.1.0 开始支持通过 SPI 扩展鉴权能力。服务端会根据 application.properties 中的 nacos.core.auth.system.type 选择一个鉴权插件,用它完成身份认证和权限校验。

鉴权插件回答的问题是:当前请求是谁发起的,它是否可以对目标资源执行这个操作

IdentityContext + Resource + Action -> 允许或拒绝

如果你只是想开启 Nacos 自带的鉴权能力,请先阅读运维手册 - 权限校验。如果你要接入企业身份系统,请阅读 OIDC/OAuth2 认证。本文更关注插件模型、内置插件边界和扩展开发。

鉴权插件中的概念

身份信息 IdentityContext

IdentityContext 是请求发起方在鉴权插件中的身份描述。不同插件可以使用不同的身份材料。

常见身份材料包括:

身份材料典型来源
usernamepassword默认 Nacos 鉴权登录
accessToken默认 Nacos 鉴权或兼容 token 传递
Authorization: Bearer ...OIDC/OAuth2、默认 Nacos token
access key、signatureRAM 或自定义签名类插件
remote_ip请求来源地址,Nacos 会默认注入

插件通过 identityNames() 声明自己需要从请求中提取哪些身份字段。服务端会把这些字段放入 IdentityContext,再交给插件判断。

资源 Resource

Resource 是请求要操作的对象。资源由 Nacos 的控制器、协议层和资源解析器生成,鉴权插件不应该重新定义 Nacos 的资源模型。

常见字段如下:

字段说明
namespaceId资源所在命名空间。部分全局接口可能为空。
group配置分组或服务分组。部分接口可能为空。
name资源名,例如配置 dataId、服务名,或控制台资源名。
type资源类型,对应模块或显式资源类型。
properties额外信息,例如 gRPC 请求名、@Secured 标签等。

操作 Action

Nacos 当前主要使用两类操作:

操作说明
r读、查询、列表、订阅等读操作。
w创建、更新、删除、发布等写操作。

内置鉴权实现

Nacos 3.2 提供以下内置鉴权实现。它们都通过同一套鉴权 SPI 接入,但身份来源和权限模型不同。

插件类型适用场景说明
nacos默认用户名、密码、token 和 RBACNacos 自带的默认实现。适合可信内网中的基础访问控制。
ldap已有 LDAP 用户体系LDAP 负责身份认证,Nacos 继续负责 token、角色和权限。3.2 起 LDAP 作为独立可选插件提供。
oidc企业 SSO、OAuth2/OIDC IdP通过 OIDC/OAuth2 接入 Keycloak、Okta、Auth0、Microsoft Entra ID 等身份提供方。
自定义类型企业自定义安全体系由用户实现 AuthPluginService 并放入服务端 classpath。

默认 Nacos 鉴权实现

默认 Nacos 鉴权实现的插件类型是 nacos。它提供用户名密码登录、JWT token、用户管理、角色管理、权限管理,以及默认 AI 资源可见性实现。

开启时通常需要配置:

nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=true
nacos.core.auth.admin.enabled=true
nacos.core.auth.console.enabled=true
nacos.core.auth.server.identity.key=${custom_server_identity_key}
nacos.core.auth.server.identity.value=${custom_server_identity_value}
nacos.core.auth.plugin.nacos.token.secret.key=${custom_base64_token_secret_key}

默认实现使用 RBAC 模型:

对象说明
UserNacos 本地用户。
Role绑定到用户的角色。
Permission绑定到角色的资源和操作。

ROLE_ADMIN 是全局管理员角色。拥有该角色的用户可以访问所有资源和控制台管理功能。

默认资源权限通常使用以下格式:

{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/skill/example-skill

默认鉴权实现提供的 v3 Auth API

/v3/auth/* 这组 API 不是 Nacos Core 的通用 API,而是默认 Nacos 鉴权实现提供的插件 API。文档和使用时都应该把它们归在默认鉴权实现下面。

API方法说明鉴权状态
/v3/auth/user/loginPOST使用用户名和密码登录,返回 accessTokennacosldap 类型支持该接口。公开登录接口。
/v3/auth/user/adminPOST初始化管理员用户 nacos。仅在还没有全局管理员时可用。初始化入口,用后即关闭。
/v3/auth/userPOST创建本地用户。需要 console/users 写权限。
/v3/auth/userPUT修改用户密码。管理员可改任意用户,普通用户只能改自己。需要身份校验。
/v3/auth/userDELETE删除本地用户,不能删除全局管理员。需要 console/users 写权限。
/v3/auth/user/listGET分页查询用户。需要 console/users 读权限。
/v3/auth/user/searchGET按用户名模糊搜索。需要 console/users 写权限。
/v3/auth/rolePOST创建角色或给用户绑定角色。需要 console/roles 写权限。
/v3/auth/roleDELETE删除角色,或移除用户上的某个角色。需要 console/roles 写权限。
/v3/auth/role/listGET分页查询角色。需要 console/roles 读权限。
/v3/auth/role/searchGET按角色名模糊搜索。需要 console/roles 读权限。
/v3/auth/permissionPOST给角色添加权限。需要 console/permissions 写权限。
/v3/auth/permissionDELETE删除角色上的权限。需要 console/permissions 写权限。
/v3/auth/permission/listGET分页查询权限。需要 console/permissions 读权限。
/v3/auth/permissionGET判断权限是否重复。需要 console/permissions 读权限。

LDAP 鉴权插件

LDAP 插件类型是 ldap。Nacos 3.2 起,LDAP 插件从默认鉴权实现中分离为独立可选插件。

LDAP 插件的边界是:

  • LDAP 负责校验用户名和密码。
  • Nacos 仍然签发登录 token。
  • Nacos 仍然使用本地角色和权限做授权。
  • 登录接口仍然使用 /v3/auth/user/login

启用示例:

nacos.core.auth.system.type=ldap
nacos.core.auth.enabled=true
nacos.core.auth.admin.enabled=true
nacos.core.auth.console.enabled=true
nacos.core.auth.ldap.url=ldap://localhost:389
nacos.core.auth.ldap.basedc=dc=example,dc=org
nacos.core.auth.ldap.userDn=cn=admin,${nacos.core.auth.ldap.basedc}
nacos.core.auth.ldap.password=admin
nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org
nacos.core.auth.ldap.filter.prefix=uid

部署时请确认:

  • nacos-ldap-auth-plugin-<version>.jar 已在 Nacos 的 plugins/ 目录或 classpath 中。
  • org.springframework.ldap:spring-ldap-core 相关 jar 已放入 plugins/ 目录。

OIDC/OAuth2 鉴权插件

OIDC/OAuth2 插件类型是 oidc。它面向企业 SSO 和外部身份提供方,支持通过 OIDC Discovery 接入 Keycloak、Okta、Auth0、Microsoft Entra ID 等 IdP。

它和默认 Nacos 鉴权的差异是:

  • 身份认证由外部 IdP 完成。
  • 控制台登录使用 /v1/auth/oidc/* 兼容接口完成浏览器跳转和回调。
  • Java SDK 可以使用 OAuth2 Client Credentials flow 获取 bearer token。
  • Nacos 本地用户、角色、权限和密码管理不再是身份源。
  • 默认 /v3/auth/user/login 不适用于 oidc 类型。
  • 如果未配置外部授权端点,当前实现会默认放行非管理员授权判断。

启用示例:

nacos.core.auth.system.type=oidc
nacos.core.auth.enabled=true
nacos.core.auth.admin.enabled=true
nacos.core.auth.console.enabled=true
nacos.core.auth.plugin.oidc.issuer-uri=https://idp.example.com/realms/nacos
nacos.core.auth.plugin.oidc.client-id=nacos-server
nacos.core.auth.plugin.oidc.client-secret=${client_secret}
nacos.core.auth.plugin.oidc.scope=openid profile email

详细配置、Keycloak 示例和排查方法请参考运维手册 - OIDC/OAuth2 认证

服务端插件开发

开发服务端鉴权插件时,需要依赖鉴权插件 API:

<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-auth-plugin</artifactId>
<version>${project.version}</version>
</dependency>

随后实现 com.alibaba.nacos.plugin.auth.spi.server.AuthPluginService,并通过 Java SPI 注册。

方法说明
getAuthServiceName()返回插件名,需要和 nacos.core.auth.system.type 对应。
identityNames()声明插件需要从请求中提取的身份字段。
enableAuth(action, type)判断指定操作和资源类型是否需要鉴权。
validateIdentity(identityContext, resource)校验身份,并把已认证用户等信息写入 IdentityContext
validateAuthority(identityContext, permission)校验身份是否拥有目标资源的目标操作权限。
isLoginEnabled()判断控制台是否展示插件提供的登录能力。
isAdminRequest()判断当前请求是否属于管理员初始化流程。

插件打包后放入 ${nacos-server.path}/plugins,并配置:

nacos.core.auth.system.type=${authServiceName}
nacos.core.auth.enabled=true

重启后,可以在 ${nacos-server.path}/logs/nacos.log 中查看插件加载日志。

客户端鉴权插件

客户端鉴权插件负责把身份材料注入到请求中。服务端仍然由当前选中的鉴权插件做最终判断。

Java 客户端内置了几类常用实现:

客户端实现身份材料说明
默认 Nacos 实现usernamepasswordaccessToken对接服务端默认 nacosldap 登录接口。
RAM 实现accessKeysecretKey、签名面向阿里云 RAM 兼容场景。
OIDC/OAuth2 实现Authorization: Bearer ...accessToken使用 OAuth2 Client Credentials flow 获取 token。

默认 Nacos 客户端示例:

Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "localhost:8848");
properties.setProperty(PropertyKeyConst.USERNAME, "nacos");
properties.setProperty(PropertyKeyConst.PASSWORD, "nacos");
NamingFactory.createNamingService(properties);
ConfigFactory.createConfigService(properties);

OIDC/OAuth2 客户端示例:

Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "localhost:8848");
properties.setProperty("nacos.client.auth.oidc.issuer-uri", "https://idp.example.com/realms/nacos");
properties.setProperty("nacos.client.auth.oidc.client-id", "nacos-client");
properties.setProperty("nacos.client.auth.oidc.client-secret", "${client_secret}");
properties.setProperty("nacos.client.auth.oidc.scope", "openid");
NamingFactory.createNamingService(properties);
ConfigFactory.createConfigService(properties);

自定义 Java 客户端鉴权插件需要实现 com.alibaba.nacos.plugin.auth.spi.client.ClientAuthService,或继承 com.alibaba.nacos.plugin.auth.spi.client.AbstractClientAuthService

方法说明
login(properties)初始化或刷新身份材料。
setServerList(serverList)获取客户端当前服务端地址列表。
setNacosRestTemplate(template)获取 Nacos HTTP 客户端,便于执行登录或刷新。
getLoginIdentityContext(resource)返回需要注入到请求中的身份材料。
shutdown()释放插件资源。

与可见性插件的关系

鉴权和可见性经常一起出现,但它们解决的问题不同:

  • 鉴权判断当前身份是否能访问一个指定资源。
  • 可见性判断一个资源是否应该出现在详情、列表或搜索结果中。

可见性插件可以复用鉴权插件做显式授权判断,例如默认实现会使用 @@visibility/{namespaceId}/{resourceType}/{resourceName} 这类资源名向当前鉴权插件查询权限。更多说明请参考可见性插件