Files
Academic-Affairs-System/docs/plugin-sdk.md
biss 05683e502a 第二阶段已完成:统一插件平台已从“内置功能开关”扩展为可安装、签名校验、版本激活和回滚的插件系统。
主要成果:
- 新增独立插件 SDK:[PluginContracts.cs (line 11)](E:/jiaowu/src/Jiaowu.Plugin.Abstractions/PluginContracts.cs:11)
- 支持 RSA-PSS/SHA-256 签名插件包、Host API 兼容性和 ZIP 安全检查:[PluginPackageValidator.cs (line 14)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/Plugins/PluginPackageValidator.cs:14)
- 支持暂存、待激活、重启装载、失败记录、版本回滚:[PluginPackageService.cs (line 32)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/Plugins/PluginPackageService.cs:32)
- 插件可注册控制器、服务、数据库迁移、后台任务和事件处理器
- 外部插件 API 统一使用 /api/plugin-extensions/{pluginId},并受启用状态中间件控制
- 插件中心新增 ZIP/SIG 上传、状态展示、激活、回滚和删除功能:[PluginsView.vue (line 212)](E:/jiaowu/web/src/views/PluginsView.vue:212)
- 提供可运行示例插件:[SamplePlugin.cs (line 10)](E:/jiaowu/samples/Jiaowu.SamplePlugin/SamplePlugin.cs:10)
- 提供打包签名脚本:[package-plugin.ps1](E:/jiaowu/scripts/package-plugin.ps1)
- 完整开发文档:[plugin-sdk.md (line 1)](E:/jiaowu/docs/plugin-sdk.md:1)
- 系统版本已调整为 3.0.0-beta1
2026-10-01 10:22:46 +08:00

93 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 明序插件 SDK
统一插件平台只装载经过受信任发布者 RSA 签名的后端插件。上传、激活和运行是三个独立阶段:上传后先暂存;管理员标记某个版本为待激活;服务重启时再次验证签名并装载,成功后才成为活动版本。
## 创建插件
插件项目面向 `net10.0`,引用 `src/Jiaowu.Plugin.Abstractions`。可以从 `samples/Jiaowu.SamplePlugin` 复制起步。入口类型必须实现 `IJiaowuPluginModule`:
```csharp
public sealed class MyPluginModule : IJiaowuPluginModule
{
public void ConfigureServices(
IServiceCollection services,
IConfiguration configuration)
{
services.AddScoped<MyPluginService>();
}
}
```
插件控制器必须使用 `/api/plugin-extensions/{pluginId}` 前缀,并自行声明 `[Authorize]`、角色和数据范围校验。插件开关只决定扩展是否开放,不能替代业务授权。
## plugin.json
包根目录必须包含 `plugin.json`,后端程序集放在 `backend/`:
```json
{
"id": "school.example",
"name": "学校示例插件",
"description": "插件用途说明",
"version": "1.0.0",
"publisherId": "school-it",
"hostApiVersion": "1",
"category": "扩展插件",
"backendAssembly": "backend/School.Example.dll",
"moduleType": "School.Example.ExamplePluginModule",
"capabilities": ["example.read"]
}
```
插件 ID 和版本一旦发布不能原地覆盖。升级必须使用新的语义版本。
## 数据迁移、事件和后台任务
- 实现 `IPluginDatabaseMigration` 声明 SQLite/MySQL 迁移语句。每个迁移以 `(PluginId, MigrationId)` 唯一记录,并在事务中只执行一次。
- 实现 `IPluginBackgroundTask` 注册定时任务。宿主强制最短 30 秒间隔,并隔离记录任务异常。
- 通过 `IPluginEventHandler<TEvent>` 订阅事件,使用 `AddPluginEventHandler<TEvent, THandler>()` 注册;通过 `IPluginEventPublisher` 发布事件。
迁移只应操作本插件拥有的表。不要修改 Identity、成绩、学籍等核心表,也不要在迁移中删除业务数据。
## 发布者密钥
私钥只保存在发布流水线或密钥管理系统,服务器只部署公钥。示例生成命令:
```powershell
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out school-it-private.pem
openssl rsa -pubout -in school-it-private.pem -out school-it-public.pem
```
生产配置:
```dotenv
Plugins__StoragePath=/var/lib/jiaowu/plugins
Plugins__TrustedPublishers__0__Id=school-it
Plugins__TrustedPublishers__0__PublicKeyPath=/etc/jiaowu/plugin-publishers/school-it-public.pem
```
服务账号需要读取公钥、读写插件存储目录;其他普通账号不应具有写权限。
## 打包与签名
仓库脚本会执行 Release 发布、生成 ZIP,并使用 RSA-PSS/SHA-256 生成分离签名:
```powershell
./scripts/package-plugin.ps1 `
-Project samples/Jiaowu.SamplePlugin/Jiaowu.SamplePlugin.csproj `
-Manifest samples/Jiaowu.SamplePlugin/plugin.json `
-PrivateKey C:/secure/school-it-private.pem
```
产物位于 `.artifacts/plugins`。把 `.zip` 和同名 `.sig` 一起上传到插件中心。
## 激活、升级与回滚
1. 先执行宿主数据库迁移并启动包含插件平台的服务版本。
2. 在插件中心上传 ZIP 和 SIG;签名、路径、大小、清单和 Host API 必须全部通过。
3. 点击“激活”,版本进入“待重启激活”。
4. 按维护流程重启服务;宿主重新验证包、装载模块并运行插件迁移。
5. 若新版本异常,在插件中心对历史版本点击“回滚到此版本”,然后再次重启。
插件程序集在独立加载上下文中运行,但仍属于受信任的服务器代码。只应信任经过代码审查的发布者;面向不受信任第三方的插件必须使用后续的独立进程/远程服务模式。