106 lines
4.1 KiB
Markdown
106 lines
4.1 KiB
Markdown
# yh-platform-net
|
||
|
||
yunhai 基础平台的 .NET SDK(对齐 Java `yh-platform`),让 .NET 应用以与 Java 完全一致的方式接入平台核心能力:用户信息、`/oapi` 开放接口、应用签名鉴权(yh-app-auth)、CAS 单点登录(yh-auth)。
|
||
|
||
## 工程结构
|
||
|
||
```
|
||
BasePlatformDotnet/
|
||
├── src/
|
||
│ ├── Yh.Platform.Abstractions/ # 模型与契约:BoaUser/BoaGroup/BoaRoleInfo、ApiEnvelope、DException、IErrorCode
|
||
│ ├── Yh.Platform.AppAuth/ # 应用签名:SignUtil/SignCanonical/AppSignHandler/SignKeyResolver/ReplayGuard
|
||
│ ├── Yh.Platform.OpenApi/ # /oapi 客户端:用户/组织/应用三域 + 双形态门面(静态 YschBaseOpenApi / 实例 BaseOpenApi)
|
||
│ └── Yh.Platform.Auth/ # CAS SSO:CasServiceTicketValidator/CasAuthenticationHandler、BoaUserContext、UserContextHolder
|
||
├── tests/ # xunit:Abstractions/AppAuth/OpenApi/Auth 四个测试工程
|
||
├── samples/Yh.Platform.Sample.Web/ # ASP.NET Core 集成示例
|
||
├── contract/ # 跨语言契约工件
|
||
│ ├── sign-protocol.md # 签名协议权威定义(Java/.NET 共同遵守)
|
||
│ ├── openapi-oapi.yaml # UserBase /oapi OpenAPI 规范(38 个端点)
|
||
│ └── fixtures/ # 信封样例与 13 组签名测试向量(tools/gen_sign_vectors.py 独立生成)
|
||
└── tools/gen_sign_vectors.py # 签名向量生成器(独立 Python 实现做双向对拍)
|
||
```
|
||
|
||
## 多目标框架
|
||
|
||
`net5.0; net8.0`:net5.0 供存量 GrowthHealth 等老项目使用,net8.0 供新项目。依赖版本由 `Directory.Packages.props`(CPM,等价 Java BOM)统一管理,net5.0 走条件版本兜底。
|
||
|
||
## 快速开始
|
||
|
||
### 1. 注册服务
|
||
|
||
```csharp
|
||
builder.Services.AddYhOpenApi(builder.Configuration); // yh:open 配置节
|
||
builder.Services.AddYhAuth(builder.Configuration); // yh:sso 配置节(CAS)
|
||
```
|
||
|
||
```json
|
||
{
|
||
"yh": {
|
||
"open": {
|
||
"BaseHost": "http://base.bestsch.com",
|
||
"BasePath": "/userbase",
|
||
"AppKey": "your-app-key",
|
||
"AppSecret": "your-app-secret"
|
||
},
|
||
"sso": {
|
||
"CasServerUrlPrefix": "https://sso.example.com/cas"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 调用开放接口
|
||
|
||
```csharp
|
||
// 静态门面(高频读)
|
||
var user = await YschBaseOpenApi.GetUserInfoAsync(loginName);
|
||
var tree = await YschBaseOpenApi.GetGroupTreeAsync();
|
||
|
||
// 实例客户端(低频写、需精细控制)
|
||
var role = await userClient.SwitchIdentityAsync(userId, roleId, schoolId);
|
||
```
|
||
|
||
响应解析为"信封感知":成功返回裸数据;业务失败(HTTP 200 + `{code≠0, msg, data}`)抛 `DException`,`Code`/`Data` 原样携带服务端内容。
|
||
|
||
### 3. 应用签名(服务端验签 / 客户端签名)
|
||
|
||
```csharp
|
||
builder.Services.AddYhAppAuth(builder.Configuration); // SignKeyResolver/ReplayGuard/AppAuthVerifier + 客户端 AppSignHandler
|
||
```
|
||
|
||
校验签名三件套(`X-App-Key` / `X-Timestamp` / `X-Signature`):
|
||
|
||
```csharp
|
||
var ok = await verifier.VerifyAsync(appKey, timestamp, signature, "GET", "/oapi/user/byId?id=1", nonce);
|
||
```
|
||
|
||
签名规则见 [contract/sign-protocol.md](contract/sign-protocol.md):
|
||
- 数据级:`HMAC_SHA256(secret, data + ts)` 小写 hex
|
||
- 请求级:`HMAC_SHA256(secret, METHOD\npath?sortedQuery\nts)` Base64
|
||
|
||
密钥解析链:Redis → MemoryCache → UserBase 兜底。
|
||
|
||
### 4. 用户上下文
|
||
|
||
```csharp
|
||
var boaUser = BoaUserContext.Get(); // 当前请求 BoaUser(AsyncLocal)
|
||
var login = UserContextHolder.Get(); // 当前请求 LoginUser
|
||
```
|
||
|
||
## 测试
|
||
|
||
```bash
|
||
dotnet test yh-platform-net.sln
|
||
```
|
||
|
||
覆盖:模型双序列化对拍、签名向量对拍(13 组独立 Python 生成向量)、URL 规范化、信封解析(成功/业务失败/HTTP 错误)、CAS XML 提取、用户上下文生命周期。
|
||
|
||
## 与 Java 侧对应关系
|
||
|
||
| .NET | Java |
|
||
|---|---|
|
||
| Yh.Platform.Abstractions | yh-platform-utils(模型) |
|
||
| Yh.Platform.AppAuth | yh-app-auth-spring-boot-starter |
|
||
| Yh.Platform.OpenApi | yh-openapi-client |
|
||
| Yh.Platform.Auth | yh-auth-core + yh-auth-spring-boot-starter |
|