跳到正文

02 三角接线:HiMarket × Higress × Nacos × 企业 SSO ​

一句话:三角接线的实质是“引用而非复制”:HiMarket 只在 ProductRef 里记“能力对应 Higress 的哪条路由、Nacos 的哪份配置”,OIDC 把企业 IdP 的 subject 映射成 Developer,配置面管关系与授权、流量面管放行与计量、注册面管内容事实;边界是三层各自演进且互不校验,路由改名、5 分钟同步滞后、ID Token 未验签、内网域被过滤成空地址,任一错位都先在消费端调用时暴露。

接 01 篇《HiMarket 底座与五类市场》。01 篇回答了“HiMarket 里面有什么”(六层架构、当前快照 28 个 Controller、API Product 模型),本篇回答“HiMarket 怎么跟 Higress、Nacos、企业 SSO 长在一起”——它是怎么融入企业生态的。结论均来自本地源码(himarket-server,commit 3a63fc5)并标注到类/方法级。


一、一句话定位:HiMarket 不是孤岛,是三层结构 ​

HiMarket 对外呈现为"一个市场门户",但它的骨架是三层:

层组件角色一句话
市场/门户层HiMarket(himarket-server + admin + frontend)元信息 + 关系 + 契约管"有什么、谁能用、授权范围与计量事实"——不跑业务流量;凭证签发与注入在数据面 Broker
运行时/网关层Higress(AI 网关)流量 + 执行 + 治理管"调用怎么放行、转发到哪、限流计量"——承载业务流量
内容/注册层Nacos(AI 内容注册中心)内容 + 规格 + 地址管"MCP Server 配置、Agent 规格、Skill 工具定义、Worker 地址"——能力的事实来源

外加一个身份维度:企业 IdP(飞书/企微/钉钉/Azure AD/Keycloak 等)通过 OIDC 与 HiMarket 打通,解决"人是谁、能进哪个门户"。

谁不干什么,比谁干什么更重要:

  • HiMarket 不直接转发调用——流量走 Higress;
  • Nacos 不直接进业务链路——它被 HiMarket 拉取/同步,产物是元数据与配置;
  • Higress 不存市场关系——谁订阅了什么产品、授权范围是什么,在市场 DB;消费者凭证与上游服务凭证分属不同域,上游密钥由 Vault/KMS 管理。

二、三角关系源码证据链(已实读) ​

2.1 关系的中枢:ProductRef(产品↔能力引用) ​

一切接线围绕 Product(可售能力) 和 ProductRef(引用) 展开。一个 Product 通过 ProductRef 指向两类外部事实:Higress 上的路由 或 Nacos 里的配置。

ProductRefResult(himarket-server dto/result/product/ProductRefResult.java):

java
public class ProductRefResult {
    private String productId;
    private SourceType sourceType;      // API_DEFINITION / GATEWAY / NACOS 等
    private String gatewayId;
    private APIGRefConfig apigRefConfig;
    private APIGRefConfig adpAIGatewayRefConfig;
    private APIGRefConfig apsaraGatewayRefConfig;
    private HigressRefConfig higressRefConfig;  // 引用 Higress 路由
    private String nacosId;             // 引用 Nacos 实例
    private NacosRefConfig nacosRefConfig;      // Nacos 里的目标
}

重要校正:ProductRefResult 不包含 mcpConfig、agentConfig、modelConfig,也不包含凭证。GET /products/{id}/ref 返回的是引用元数据,不是可直接调用的连接配置。

两种引用配置的字段(himarket-dal support/product/):

java
// HigressRefConfig:指向 Higress 上已存在的 AI 路由
public class HigressRefConfig {
    private String routeName;        // HTTP 路由名(通用)
    private String mcpServerName;    // Higress MCP Server 名
    private String modelRouteName;   // 模型路由名(MODEL_API 用)
}

// NacosRefConfig:指向 Nacos 里的 MCP/Agent 配置
public class NacosRefConfig {
    private String mcpServerName;    // MCP Server(MCP_SERVER 用)
    private String agentName;        // Agent(AGENT_API 用)
    // + namespaceId / group 等寻址信息
}

结论:HiMarket 的"关联"是一个引用模型——Product 不复制能力,只记录"能力在哪(Higress 路由 / Nacos 配置)"。这就是契约化接入的根:满足引用契约即可被市场化管理,无需重开发。

2.2 HiMarket → Nacos:能力内容的事实来源 ​

类职责证据
NacosController + NacosServiceImplNacos 实例导入/管理(地址、账号、缓存客户端)NacosInstanceRepository 持久化;AiMaintainerService 按实例缓存
McpConfigSyncHelper#fetchRemoteConfig按 nacosId + NacosRefConfig 从 Nacos 拉取 MCP 配置nacosService.fetchMcpConfig(param.getNacosId(), nacosRef)(service/mcp/McpConfigSyncHelper.java:169)
SkillWorkerMetadataSyncTask每 5 分钟定时从 Nacos 同步 Skill / Worker 元数据,生成/更新 Product 草稿@Scheduled(fixedDelay = 300_000)(service/task/SkillWorkerMetadataSyncTask.java:53),使用 Nacos AI SDK 的 SkillSummary / AgentSpecSummary
ProductServiceImpl创建 Skill/Worker 类产品时取默认 Nacos 实例nacosService.getDefaultNacosInstance()(service/impl/ProductServiceImpl.java:203)
NacosServiceImpl连接参数:PropertyKeyConst.SERVER_ADDR/NAMESPACE/USERNAME/PASSWORD,默认 context path nacosservice/impl/NacosServiceImpl.java

Nacos 在 HiMarket 里的三个用途(对应三类能力内容):

  1. MCP Server 配置:Nacos 里登记的 MCP 服务(域名/路径/凭证)→ fetchMcpConfig 拉成 McpConfigResult;
  2. Agent 规格:Nacos AI 模块的 Agent 定义 → fetchAgentConfig 拉成 agent 配置;
  3. Skill / Worker 元数据:定时任务批量同步到市场(Skill 工具规格、Worker 执行体地址)。

2.3 HiMarket → Higress:运行时网关的编排者 ​

类职责证据
GatewayController + GatewayService导入/管理网关实例(Higress 控制台地址、账号、域名)Gateway 实体
HigressOperator(service/gateway/HigressOperator.java)通过 Higress 控制台 API 操作网关:拉取 AI 路由、MCP 凭证、域名fetchAIRoute(gateway, higressRefConfig.getModelRouteName())(:273)、fetchMcpCredential(gateway, mcpServerName)(:320)
McpConfigSyncHelper发布/关联时把 MCP 配置与 Higress 侧对齐引用 GatewayService + NacosService

关键机制:HiMarket 不是替 Higress 建路由,而是引用 Higress 上已存在的路由(mcpServerName / modelRouteName 是 Higress 侧的命名)。生产环境应发布一个稳定产品端点,再由配置发布器映射到目标路由;不能把 Nacos 中的临时地址直接暴露给消费端。

2.4 消费端拿到的“连接描述”:McpConfigResult.toTransportConfig() ​

HiMarket 内的 toTransportConfig() 从 mcpServerConfig.domains 拼出连接地址,当前源码逻辑如下(简化):

java
public McpTransportConfig toTransportConfig() {
    // 过滤 intranet 域,取公网域名
    DomainResult domain = mcpServerConfig.getDomains().stream()
        .filter(d -> !"intranet".equalsIgnoreCase(d.getNetworkType()))
        .findFirst().orElse(null);
    String baseUrl = scheme + "://" + domain + (port > 0 ? ":" + port : "");
    String url = baseUrl + (path.startsWith("/") ? path : "/" + path);
    return McpTransportConfig.builder()
        .mcpServerName(mcpServerName)
        .transportMode(transportMode)   // streamable_http / sse
        .url(url)
        .build();
}

校正三点:

  1. 该对象只含 mcpServerName / transportMode / url,不含 tools 白名单,也不含凭证。调用头由消费端的 CredentialContext 另行注入。
  2. 源码会过滤 intranet 域并取第一个非内网域;企业私有部署若只有内网地址,会得到空配置。生产实现必须显式配置“投递域名”,不能沿用该默认选择。
  3. GET /products/{id}/ref 返回的是 ProductRefResult(引用元数据),不是 McpTransportConfig。不能把两者混为“公开获取连接配置”。

因此,HiMarket 的契约落点是“引用 + 稳定产品端点 + 订阅授权”,不是“把上游连接和密钥打包给客户端”。凭证应由网关或凭证中介在调用时注入。


三、端到端数据流(发布 → 订阅 → 消费) ​


四、企业 SSO 融入:OIDC 身份链路(已实读源码) ​

4.1 HiMarket 的身份形态:OIDC Client(对接企业 IdP) ​

HiMarket 不是自建身份库对外发身份,而是对接企业既有的 OIDC Provider。开发者(企业员工)用企业账号登录开发者门户。

OidcController(controller/OidcController.java)三个端点:

text
GET /developers/oidc/providers          → 列出可用 IdP(provider/displayName/图标)
GET /developers/oidc/authorize?provider=xxx&apiPrefix=/api/v1
                                       → 302 重定向到企业 IdP 授权页
GET /developers/oidc/callback?code=xxx&state=yyy
                                       → 换 token → 绑定 Developer → 返回 AuthResult

4.2 Provider 配置:挂在 Portal 上(多租户维度) ​

OidcServiceImpl.findOidcConfig()(:191)——OidcConfig 存在 Portal 的 PortalSettingConfig 里:

java
private OidcConfig findOidcConfig(String provider) {
    PortalResult portal = portalService.getPortal(contextHolder.getPortal());
    List<OidcConfig> oidcConfigs = portal.getPortalSettingConfig().getOidcConfigs();
    // 匹配 provider 且 enabled==true
}

企业生态含义:每个租户(企业/部门)可以配自己的 IdP 集合。一个 Portal = 一个企业 = 一套 SSO。OidcConfig 字段:provider / displayName / enabled / clientId / clientSecret / authCodeConfig(tokenEndpoint, userInfoEndpoint, redirectUri 规则) / 域名白名单。

4.3 授权码流程实现(OidcServiceImpl) ​

text
1. buildAuthorizationUrl()   → 构造 IdP 授权 URL(client_id + redirect_uri + state)
2. state = Base64(JSON{provider, apiPrefix, nonce, timestamp})   ← 防 CSRF + 记录登录目标
3. handleCallback()          → 校验 state(10 分钟有效)→ requestToken(code) → getUserInfo
4. getUserInfo()             → 优先解析 ID Token(验 exp);缺失则 fallback UserInfo endpoint
5. 身份绑定                  → DeveloperServiceImpl.findByProviderAndSubject(provider, subject)
                              → 存在即登录,不存在则按自动注册策略建 Developer
6. 返回 AuthResult           → HiMarket 自签 token(TokenService),后续 API 用

4.4 生产注意(源码直读发现的坑,已在文档里记录) ​

项源码状态生产要求
ID Token 签名校验// TODO: Verify the ID token signature with the provider JWK set.(OidcServiceImpl:310)必须启用 JWK 验签(对接企业 IdP 的 discovery 端点拉 jwks_uri)
state 有效期10 分钟(:227)合理;apiPrefix 需与 redirect_uri 白名单联动校验
redirect_uribuildRedirectUri(request, authCodeConfig) 动态拼生产必须按 IdP 侧白名单严格配置,防 open redirect
自动注册findByProviderAndSubject 不存在时自动建 Developer需按企业策略开关:仅 SSO 登录 vs 需管理员审批入租户

五、融入企业生态的整体架构(含我们平台的整合位) ​

要点(对应 07-32 集成接线设计):

  • HiMarket = 人类入口与市场控制面:市场关系、订阅、审批与目录在这里;它管“谁能用什么”,但不承载业务流量、也不保管上游长期密钥;
  • Higress = 运行时出口:业务流量唯一出口,限流/计量在网关执行(07-32 接缝 4、5 的落点);
  • AuthZ/Credential Broker = 授权与凭证中介:校验订阅、工具白名单与配额,注入上游短期凭证;
  • Nacos = 内容事实源:MCP/Agent/Skill/Worker 的配置与元数据从这里来(07-32 接缝 1、2 的落点);
  • OIDC = 身份映射(接缝 3):企业 IdP 的 subject ↔ HiMarket Developer ↔(未来)agentscope-service 的 user,三层身份映射;
  • 我们体系的整合位:消费端(qwenpaw 实例 / agentscope 执行体)作为 MCP/HTTP 客户端调用稳定产品端点,只持有平台凭证,不持有上游密钥。

六、待实证清单(对应 #18 接线,随部署推进逐项销项) ​

#实证项方法状态
1HiMarket 最小集部署(mysql+nacos+server+admin+frontend+sandbox)compose 起栈✅(未含 Higress)
2Nacos 登记 + 默认实例识别管理端登记 → getDefaultNacosInstance 可查✅
3MCP Server 从 Nacos 拉配置(fetchMcpConfig)创建 MCP 产品 → 检查 McpConfigResult 内容⏳
4Higress 路由对齐(fetchAIRoute/fetchMcpCredential)导入 Higress → Link MODEL_API → 检查路由⏳
5Skill/Worker 5 分钟自动同步在 Nacos 放 Skill → 等同步 → 市场出现草稿✅(POC)
6OIDC 对接企业 IdP(飞书/Keycloak)配置 OidcConfig → authorize 302 → callback 绑 Developer⏳
7凭证中介 + 数据面消费闭环Consumer 凭证 → 网关 → 真实 MCP → 计量⏳

七、与 00 总纲的关系说明 ​

本篇替代早期计划中的“供给链/订阅/网关”拆分篇,作为接线专篇横切 01/03/04/05。实证结果回填 00 篇台账与 04 篇;生产架构、凭证中介与验收门槛以 05 篇为准。

把 AI 工程讲到既懂也会用