# Iam Third Party Integration

> Skill: 第三方应用接入 IAM（iam-boot-mini）

- Skill: `51studio/iam-third-party-integration` (Agent Skill)
- Install (CLI): `npx skillmds@latest add 51studio/iam-third-party-integration`
- Raw SKILL.md: https://api.skillmd.com/api/skills/51studio/iam-third-party-integration/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: 51studio (https://skillmd.com/u/51studio)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/51studio/iam-third-party-integration

---

# Skill: 第三方应用接入 IAM（iam-boot-mini）

## 用途

指导如何将第三方系统接入 `iam-boot-mini` 项目，复用其登录/注册、身份验证、组织管理和权限管理能力。

USE FOR: 第三方系统接入 IAM、统一身份认证、OAuth2 对接、开放平台 API 调用、组织权限同步。

## 适用场景

- 第三方后端服务需要调用 IAM 的用户/部门/角色/权限管理接口。
- 第三方 Web/移动应用希望跳转 IAM 登录页完成统一认证（类 SSO）。
- 内部新模块需要复用 IAM 的用户与权限数据。
- 为外部合作伙伴开放受控的 API 访问。

## 前置条件

- IAM 项目已启动，数据库已初始化（`sql/mysql/iam.sql` 或 `ruoyi-vue-pro.sql`）。
- 网络可达 IAM 服务，默认端口 `48080`。
- 第三方系统已确定接入形态（后端服务 / 前端应用 / 内部模块）。

## 接入方案速查

| 方案 | 适用场景 | 复杂度 | 推荐度 |
|---|---|---|---|
| **A. OAuth2 Client Credentials** | 纯后端服务调用 IAM | 低 | ⭐⭐⭐ 推荐 |
| **B. OAuth2 Authorization Code** | 第三方 Web/移动应用需用户登录 | 中 | ⭐⭐⭐ 推荐 |
| **C. OAuth2 Password** | 受信任的内部工具 | 中 | ⚠️ 谨慎使用 |
| **D. App Key + API 签名** | 无 OAuth2 场景的轻量接入 | 中 | ⭐⭐ 需二次开发 |
| **E. 同 JVM 模块依赖** | 内部新模块与 IAM 同应用 | 低 | ⭐⭐⭐ 内部复用 |

---

## 方案 A：OAuth2 Client Credentials（后端服务调用）

### 步骤

1. **在 IAM 后台创建第三方应用**
   - 接口：`POST /admin-api/system/app/create`
   - 系统自动生成对应的 OAuth2 Client（`client_id` / `client_secret`）。

2. **第三方服务获取 Access Token**

   ```http
   POST /admin-api/system/oauth2/token
   Authorization: Basic {base64(clientId:clientSecret)}
   Content-Type: application/x-www-form-urlencoded

   grant_type=client_credentials&scope=user.read
   ```

3. **调用 IAM 管理接口**

   ```http
   GET /admin-api/system/user/page
   Authorization: Bearer {accessToken}
   tenant-id: {tenantId}
   ```

4. **Token 刷新**
   - `client_credentials` 模式通常不返回 `refresh_token`。
   - Token 过期后重新用 Basic Auth 获取。

### 权限说明

- 服务账号本身没有权限，需要给该账号关联一个 IAM 用户/角色，或赋予 `super_admin`。
- 用于管理接口时，建议创建一个专门的服务账号并赋予最小权限。

---

## 方案 B：OAuth2 Authorization Code（前端应用单点登录）

### 步骤

1. **创建 OAuth2 Client，授权类型包含 `authorization_code`、`refresh_token`**。
2. **第三方前端引导用户到 IAM 登录页**。
3. **登录后调用授权接口获取 code**：

   ```http
   POST /admin-api/system/oauth2/authorize
   Authorization: Bearer {loginAccessToken}
   Content-Type: application/x-www-form-urlencoded

   response_type=code&client_id={clientId}&redirect_uri={redirectUri}&scope=user.read
   ```

4. **第三方后端用 code 换 token**：

   ```http
   POST /admin-api/system/oauth2/token
   Content-Type: application/x-www-form-urlencoded

   grant_type=authorization_code&code={code}&redirect_uri={redirectUri}&client_id={clientId}&client_secret={clientSecret}
   ```

5. **后续携带 `Authorization: Bearer {accessToken}` 访问 IAM 接口**。

### 注意事项

- `redirect_uri` 必须与创建 Client 时配置的一致。
- 简化模式（implicit）也在 `/authorize` 接口支持，但不推荐用于生产。

---

## 方案 C：OAuth2 Password（受信任内部应用）

### 步骤

```http
POST /admin-api/system/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=password&username={username}&password={password}&client_id={clientId}&client_secret={clientSecret}&scope=user.read
```

### 注意事项

- 仅用于完全受控的内部系统。
- 若账号开启 MFA，会返回 `mfaRequired=true`，需额外处理 MFA 流程。
- 泄露风险高，不建议对外使用。

---

## 方案 D：App Key + API 签名

### 前提

当前签名框架已实现与 `system_app` 表打通：

- 请求头携带 `X-App-Key`。
- 服务端从 `system_app.app_secret` 读取密钥。
- 支持 IP 白名单/黑名单和 API 权限拦截。

### 签名规则

请求头：

```http
appId: {appKey}
timestamp: {毫秒时间戳}
nonce: {10位以上随机数}
sign: {sha256签名}
```

签名字符串：

```
请求参数 + 请求体 + appId={appId}&timestamp={timestamp}&nonce={nonce} + appSecret
```

示例 Java 客户端签名：

```java
public static String sign(String appId, String appSecret, Map<String, String> params, String body) {
    SortedMap<String, String> sortedParams = new TreeMap<>(params);
    String paramStr = MapUtil.join(sortedParams, "&", "=");
    String headerStr = "appId=" + appId + "&timestamp=" + System.currentTimeMillis()
                     + "&nonce=" + RandomUtil.randomNumbers(16);
    String signStr = paramStr + body + headerStr + appSecret;
    return SecureUtil.sha256(signStr);
}
```

### 安全增强

- 在 IAM 后台为应用配置 `ipWhitelist` / `ipBlacklist`。
- 在 `system_app_api_permission` 中配置该应用可调用的 API。
- 请求会自动经过 `AppIpInterceptor` 和 `AppApiPermissionInterceptor` 校验。

---

## 方案 E：同 JVM 内部模块复用

### 步骤

1. 在第三方模块的 `pom.xml` 中引入：

   ```xml
   <dependency>
       <groupId>cn.iocoder.boot</groupId>
       <artifactId>iam-module-system</artifactId>
   </dependency>
   ```

2. 注入 `AdminUserApi`、`DeptApi`、`PermissionApi` 等接口：

   ```java
   @Resource
   private AdminUserApi adminUserApi;
   @Resource
   private PermissionApi permissionApi;

   AdminUserRespDTO user = adminUserApi.getUser(userId);
   boolean hasPermission = permissionApi.hasAnyPermissions(userId, "system:user:create");
   ```

### 限制

仅适用于与 IAM 同属一个 Spring Boot 聚合应用的内部模块。

---

## 常用管理接口速查

### 用户管理

| 功能 | 接口 |
|---|---|
| 分页查询用户 | `GET /admin-api/system/user/page` |
| 用户详情 | `GET /admin-api/system/user/get?id={id}` |
| 创建用户 | `POST /admin-api/system/user/create` |
| 更新用户 | `PUT /admin-api/system/user/update` |
| 分配用户角色 | `POST /admin-api/system/permission/assign-user-role` |

### 部门（组织）管理

| 功能 | 接口 |
|---|---|
| 部门列表 | `GET /admin-api/system/dept/list` |
| 创建部门 | `POST /admin-api/system/dept/create` |
| 更新部门 | `PUT /admin-api/system/dept/update` |

### 角色/权限管理

| 功能 | 接口 |
|---|---|
| 创建角色 | `POST /admin-api/system/role/create` |
| 分配角色菜单 | `POST /admin-api/system/permission/assign-role-menu` |
| 获取用户权限 | `GET /admin-api/system/permission/list-user-permissions?userId={userId}` |
| 校验权限 | `GET /admin-api/system/permission/check?userId={userId}&permissions={permissions}` |

### OAuth2 接口

| 功能 | 接口 |
|---|---|
| 获取 Token | `POST /admin-api/system/oauth2/token` |
| 校验 Token | `POST /admin-api/system/oauth2/check-token` |
| 撤销 Token | `DELETE /admin-api/system/oauth2/token` |
| 授权码授权 | `POST /admin-api/system/oauth2/authorize` |
| 当前用户信息 | `GET /admin-api/system/oauth2/user/get` |

---

## 独立开放 API 入口 `/open-api`

### 用途

将面向第三方的接口与 `/admin-api` 管理后台接口隔离，避免安全策略混用。

### 使用方式

在任意模块创建 `controller.open` 包下的 Controller：

```java
package cn.iocoder.yudao.module.system.controller.open.user;

@RestController
@RequestMapping("/user")
public class OpenUserController {

    @GetMapping("/get")
    public CommonResult<UserRespVO> getUser(@RequestParam Long id) {
        // ...
    }
}
```

访问路径：`/open-api/user/get`

### 自动生效的安全拦截

对 `/open-api/**` 和 `/admin-api/**` 自动生效：

1. `AppIpInterceptor`：IP 黑白名单
2. `AppApiPermissionInterceptor`：API 权限校验
3. `AppQuotaInterceptor`：调用配额
4. `AppAuditLogInterceptor`：审计日志

---

## 配置属性

### Web API 前缀

```yaml
yudao:
  web:
    admin-api:
      prefix: /admin-api
      controller: "**.controller.admin.**"
    app-api:
      prefix: /app-api
      controller: "**.controller.app.**"
    open-api:
      prefix: /open-api
      controller: "**.controller.open.**"
```

### 安全相关

```yaml
yudao:
  security:
    permit-all_urls:
      - /admin-api/system/auth/**
      - /open-api/system/auth/**
```

---

## 最佳实践

1. **优先使用 `client_credentials`**：纯后端调用首选，避免传递用户密码。
2. **每个第三方系统一个 OAuth2 Client**：便于隔离权限、监控调用、独立吊销。
3. **使用 `/open-api` 暴露第三方接口**：不要直接让外部调用 `/admin-api`。
4. **启用 IP 白名单**：生产环境为每个应用配置允许的 IP 或网段。
5. **配置 API 权限清单**：在 `system_app_api_permission` 中精确控制每个应用可调用的接口。
6. **关闭 Mock 登录**：生产环境必须设置 `yudao.security.mock-enable=false`。
7. **限制 CORS**：生产环境不要配置 `*` 来源，按具体域名配置。

---

## 故障排查

| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| `invalid_client` | client_id / secret 错误 | 检查 Basic Auth 编码 |
| `应用请求 IP 不在白名单` | IP 白名单配置不正确 | 检查 `system_app.ip_whitelist` |
| `应用没有该 API 的调用权限` | 未配置 API 权限或路径不匹配 | 检查 `system_app_api_permission` |
| `签名不正确` | appSecret 错误或非对称 | 检查 `system_app.app_secret` |
| Token 校验失败 | Token 过期或被撤销 | 调用 `/check-token` 确认 |
| 多租户下查不到应用 | 租户上下文缺失 | 确认请求携带 `tenant-id` |

---

## 相关文件

- `iam-module-system/.../controller/admin/oauth2/OAuth2OpenController.java`
- `iam-module-system/.../service/oauth2/OAuth2TokenServiceImpl.java`
- `iam-module-system/.../api/interceptor/AppIpInterceptor.java`
- `iam-module-system/.../api/interceptor/AppApiPermissionInterceptor.java`
- `iam-module-system/.../config/AppOpenApiSecurityConfiguration.java`
- `iam-framework/iam-spring-boot-starter-web/.../web/config/WebProperties.java`

---

## 版本说明

- 适用于 `iam-boot-mini` Spring Boot 3.x 分支。
- 自研 OAuth2 实现，非 Spring Authorization Server，不支持标准 OIDC/SAML（如需标准协议需二次开发）。

