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(后端服务调用)
步骤
在 IAM 后台创建第三方应用
- 接口:
POST /admin-api/system/app/create - 系统自动生成对应的 OAuth2 Client(
client_id/client_secret)。
- 接口:
第三方服务获取 Access Token
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调用 IAM 管理接口
GET /admin-api/system/user/page Authorization: Bearer {accessToken} tenant-id: {tenantId}Token 刷新
client_credentials模式通常不返回refresh_token。- Token 过期后重新用 Basic Auth 获取。
权限说明
- 服务账号本身没有权限,需要给该账号关联一个 IAM 用户/角色,或赋予
super_admin。 - 用于管理接口时,建议创建一个专门的服务账号并赋予最小权限。
方案 B:OAuth2 Authorization Code(前端应用单点登录)
步骤
创建 OAuth2 Client,授权类型包含
authorization_code、refresh_token。第三方前端引导用户到 IAM 登录页。
登录后调用授权接口获取 code:
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第三方后端用 code 换 token:
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}后续携带
Authorization: Bearer {accessToken}访问 IAM 接口。
注意事项
redirect_uri必须与创建 Client 时配置的一致。- 简化模式(implicit)也在
/authorize接口支持,但不推荐用于生产。
方案 C:OAuth2 Password(受信任内部应用)
步骤
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 权限拦截。
签名规则
请求头:
appId: {appKey}
timestamp: {毫秒时间戳}
nonce: {10位以上随机数}
sign: {sha256签名}
签名字符串:
请求参数 + 请求体 + appId={appId}×tamp={timestamp}&nonce={nonce} + appSecret
示例 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 + "×tamp=" + 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 内部模块复用
步骤
在第三方模块的
pom.xml中引入:<dependency> <groupId>cn.iocoder.boot</groupId> <artifactId>iam-module-system</artifactId> </dependency>注入
AdminUserApi、DeptApi、PermissionApi等接口:@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:
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/** 自动生效:
AppIpInterceptor:IP 黑白名单AppApiPermissionInterceptor:API 权限校验AppQuotaInterceptor:调用配额AppAuditLogInterceptor:审计日志
配置属性
Web API 前缀
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.**"
安全相关
yudao:
security:
permit-all_urls:
- /admin-api/system/auth/**
- /open-api/system/auth/**
最佳实践
- 优先使用
client_credentials:纯后端调用首选,避免传递用户密码。 - 每个第三方系统一个 OAuth2 Client:便于隔离权限、监控调用、独立吊销。
- 使用
/open-api暴露第三方接口:不要直接让外部调用/admin-api。 - 启用 IP 白名单:生产环境为每个应用配置允许的 IP 或网段。
- 配置 API 权限清单:在
system_app_api_permission中精确控制每个应用可调用的接口。 - 关闭 Mock 登录:生产环境必须设置
yudao.security.mock-enable=false。 - 限制 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.javaiam-module-system/.../service/oauth2/OAuth2TokenServiceImpl.javaiam-module-system/.../api/interceptor/AppIpInterceptor.javaiam-module-system/.../api/interceptor/AppApiPermissionInterceptor.javaiam-module-system/.../config/AppOpenApiSecurityConfiguration.javaiam-framework/iam-spring-boot-starter-web/.../web/config/WebProperties.java
版本说明
- 适用于
iam-boot-miniSpring Boot 3.x 分支。 - 自研 OAuth2 实现,非 Spring Authorization Server,不支持标准 OIDC/SAML(如需标准协议需二次开发)。