GJJ.Keystone.AspNetCore
4.3.5
dotnet add package GJJ.Keystone.AspNetCore --version 4.3.5
NuGet\Install-Package GJJ.Keystone.AspNetCore -Version 4.3.5
<PackageReference Include="GJJ.Keystone.AspNetCore" Version="4.3.5" />
<PackageVersion Include="GJJ.Keystone.AspNetCore" Version="4.3.5" />
<PackageReference Include="GJJ.Keystone.AspNetCore" />
paket add GJJ.Keystone.AspNetCore --version 4.3.5
#r "nuget: GJJ.Keystone.AspNetCore, 4.3.5"
#:package GJJ.Keystone.AspNetCore@4.3.5
#addin nuget:?package=GJJ.Keystone.AspNetCore&version=4.3.5
#tool nuget:?package=GJJ.Keystone.AspNetCore&version=4.3.5
GJJ.Keystone.AspNetCore
GJJ Keystone 体系面向 ASP.NET Core 宿主 的扩展套件:JWT 鉴权、Nacos/TongNCS / OpenTelemetry 基础设施一键注册、SM4-GCM v1 与 AES-CBC 传输加密、API 目录扫描、统一中间件管道、契约扩展等。
为什么独立成包
GJJ.Keystone.Abstractions与GJJ.Keystone.Toolkit的所有类型都可在非 Web 宿主复用,本包则把对HttpContext/IApplicationBuilder/IServiceCollection等 Web 宿主类型的依赖集中到一处。- 把中间件、过滤器、Endpoint 扩展、ActionDescriptor 扫描等明显属于"Web 边界"的能力封装进来,业务项目只需在
Program.cs调用几行扩展方法即可启动整套基础设施。
内容概览
JWT 鉴权(Auth/)
| 类型 | 用途 |
|---|---|
AddJwtAuth(...) |
一次性配置 JwtBearer + Authorization 默认策略;支持多受众(逗号 / 分号分隔)、环境强校验(env Claim)、签名 / 过期 / 算法限定 HS256、丰富的诊断日志 |
JwtAuthOptions |
配置项(Issuer / Audience / SecurityKey / ClockSkewMinutes / EnforceEnvironment / EnableDiagnostics 等) |
基础设施一键注册(Infrastructure/SystemServiceExtensions.cs)
AddGjjSystemInfrastructure(...) 统一封装:
- Nacos/TongNCS:配置中心拉取 / 热更新
- CORS:自动从配置读取
AppHosts并注册AppCors策略 - Serilog:默认官方 Console 样式 + 主文件 + diagnostic 文件 + error 文件 + Seq;应用可配置级别与输出开关
- OpenTelemetry:Tracing(AspNetCore / HttpClient / SqlClient / EFCore)→ OTLP 导出;当前代码优先读取
Observability:OtlpTraceEndpoint,旧SeqHostHTTP仅作兼容兜底,Logs 仅保留显式兼容入口 - Nacos/TongNCS:服务注册 + REST beat 心跳续约;业务健康探针由各服务
HealthController提供 - Kestrel:监听端口配置
Serilog 默认无需项目配置;需要按环境调整时,只覆盖关心的选项:
{
"Serilog": {
"ConsoleStyle": "Default",
"FileEnabled": true,
"DiagnosticFileEnabled": true,
"ErrorFileEnabled": true,
"SeqEnabled": true,
"LogDirectory": "logs",
"FileRetainedDays": 14,
"DiagnosticFileRetainedDays": 7,
"ErrorFileRetainedDays": 30,
"NacosFailureEscalationThreshold": 3,
"ErrorReminderIntervalMinutes": 5,
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning"
}
}
}
}
ConsoleStyle 支持 Default(官方跨平台样式,默认)和 None(关闭控制台)。历史 Keystone 自定义 ANSI 样式已退场,配置后会回退为 Default。
业务服务无需配置即可默认生成 logs/{ServiceName}-error-{Date}.log,只收集 Error/Fatal 并默认保留 30 天;Nacos 心跳等持续基础设施故障会按“首次 Warning、达到阈值升 Error、持续失败按间隔提醒”的节奏自动进入错误文件。可通过 ErrorFileEnabled、ErrorFileRetainedDays、NacosFailureEscalationThreshold、ErrorReminderIntervalMinutes 和 LogDirectory 覆盖。
输出 Sink 由 Keystone 统一管理,应用配置中的 Serilog:WriteTo 会被忽略,避免同一日志重复写入。
Kit 自身日志前缀统一使用 [Kit.xxx],子模块写在正文中,例如 [Kit.Auth] Validate:签名不匹配、[Kit.Pipeline] CORS:策略=AppCors,避免 [Kit.Auth/Validate] 这类带斜杠前缀影响默认控制台颜色识别。
启动诊断摘要输出完毕后,会打印 ------------------------------------------------------- 启动诊断完成 ------------------------------------------------------- 分割线,便于区分 Kit 启动摘要和后续业务后台任务日志。
完整日志链路、分流规则、Seq 地址解析和验收方式见:Serilog 统一日志与诊断说明。
通用中间件管道(Hosting/ApplicationBuilderExtensions.cs)
UseGjjCommonMiddleware(...) 串起:CORS → SM / AES 加密 → Authentication → Authorization → MapControllers,默认值即开箱可用;健康探针由业务项目自行提供 HealthController,启动摘要使用 [Kit.Pipeline],失败时打印 Error 便于排查。
传输层加密(Security/)
| 类型 | 用途 |
|---|---|
AddSMEncryption(...) / AddSMEncryptionFilters(...) |
注册 SM4 v1 信封加解密:Options 校验 + 加解密器 + 全局 ActionFilter + 中间件 |
AddAESEncryption(...) / AddAESEncryptionFilters(...) |
注册 AES-CBC 传输加解密 |
SMEncryptionMiddleware / AESEncryptionMiddleware |
v1 信封 / AES Base64 的请求解密 + 响应加密中间件 |
SMEncryptionActionFilter / AESEncryptionActionFilter |
配合 [EnableSMEncryption] / [EnableAESEncryption] 注解校验"接口是否要求加密" |
Internal/V1AadBuilder / V1EnvelopeHelpers |
v1 协议的 AAD 构造与信封校验工具 |
API 目录扫描(Reflection/ApiCatalog/ 与 Hosting/ApiCatalogControllerHelper.cs)
IApiCatalogScanner+MvcApiCatalogScanner:基于 MVCActionDescriptors+ XML 注释生成ApiCatalogResponse,支持命名空间前缀过滤、[EnableApiRegister]必标。IXmlDocProvider+XmlDocProvider:按T:/M:/P:/F:memberId 读取.xml文档(含嵌套类型+→.修复)。ApiCatalogControllerHelper.HandleAsync(...):在 Controller Action 中一行调用即可输出目录 JSON,可选携带 token 校验。
HttpContext 扩展(Extensions/HttpContextExtensions.cs)
从 JWT Claims 中解析常用字段,统一各业务的 Claim 名约定:
| 方法 | 解析字段 |
|---|---|
GetUserId() |
sub |
GetRoles() / GetPrimaryRole() |
role 或 ClaimTypes.Role |
GetUserType() |
user_type / utype / UserType |
GetDbPointCode() |
dbpoint / dbPointCode |
GetChannelCode() |
channel / channelCode |
IsSuperAdmin() |
name ∈ {GjjAll, admin, zjz} |
GetUserName() |
name |
契约 / 序列化扩展
ApiContractExtensions:把CommandResult/QueryResult<T>一行包装成对外s_ApiResult<T>,支持ToApi(mapper)惰性映射(成功时才执行 AutoMapper 等转换)。DateTimeFormatConverter:统一DateTime/DateTime?的输出格式(仅写入,读取仍走 STJ 默认)。NetworkHelper.GetIP():从HttpContext解析客户端 IP(兼容X-Forwarded-For等代理头)。
典型用法
Program.cs 一站式集成
using GJJ.Keystone.AspNetCore.Auth;
using GJJ.Keystone.AspNetCore.Hosting;
using GJJ.Keystone.AspNetCore.Infrastructure;
using GJJ.Keystone.AspNetCore.Security.SM;
var builder = WebApplication.CreateBuilder(args);
// 1) 基础设施(Nacos/TongNCS / CORS / OTel / Kestrel)
builder.Services.AddGjjSystemInfrastructure(
builder.Configuration,
builder.Configuration as IConfigurationBuilder,
serviceName: "GJJ.UniServiceHub",
hostPort: 16002);
// 2) JWT 鉴权
var jwtSecurityKey = builder.Configuration["Jwt:SecurityKey"]
?? throw new InvalidOperationException("配置缺失:Jwt:SecurityKey");
builder.Services.AddJwtAuth(o =>
{
o.Issuer = "https://auth.gjj.local";
o.Audience = "gjj-mgmt-api,gjj-portal"; // 多受众
o.SecurityKey = jwtSecurityKey;
o.NameClaimType = "sub";
o.RoleClaimType = "role";
o.EnforceEnvironment = true;
o.ExpectedEnvironment = "dev";
}, requireAuthenticatedByDefault: true);
// 3) SM4-GCM v1 传输加密
builder.Services.AddSMEncryption(o =>
{
o.Mode = "GCM";
o.Kid = "sm4-2025";
o.KeyHex = "00112233445566778899AABBCCDDEEFF";
o.AllowUnencryptedPaths = new[] { "/api/Health", "/swagger" };
}).AddSMEncryptionFilters();
// 4) MVC 控制器
builder.Services.AddControllers();
var app = builder.Build();
// 5) 通用管道:CORS → 加密 → Auth → MapControllers
app.UseGjjCommonMiddleware(opt =>
{
opt.UseCors = true;
opt.UseSmEncryption = true;
});
app.Run();
Controller 内返回标准 API 结果
using GJJ.Keystone.Abstractions.Annotations;
using GJJ.Keystone.AspNetCore.Extensions;
[ApiController]
[Route("api/[controller]")]
[EnableSMEncryption]
public class UserController : ControllerBase
{
private readonly UserService _service;
[HttpGet("{id}")]
[EnableApiRegister(ChineseName = "查询用户", Group = "用户管理")]
public async Task<S_ApiResult<UserVM>> Get(int id)
{
var query = await _service.GetByIdAsync(id);
return query.ToApi(dto => _mapper.Map<UserVM>(dto));
}
}
暴露 API 目录端点
// Program.cs 注册
builder.Services.AddApiCatalogScanner();
// 在某个 Controller 里直接返回扫描结果
[HttpGet("/__gjj/api-catalog")]
[AllowAnonymous]
public Task<IActionResult> Catalog([FromServices] IApiCatalogScanner scanner)
=> ApiCatalogControllerHelper.HandleAsync(HttpContext, scanner, new ApiCatalogEndpointOptions
{
Token = "your-secret",
TokenHeaderName = "X-ApiCatalog-Token",
ServiceName = "GJJ.UniServiceHub",
Environment = "dev"
});
设计约束
- 可单独关停:
UseGjjCommonMiddleware的每一段都受GjjPipelineOptions控制,可以按需关闭 CORS / 加密 / MapControllers,便于自定义路由分组或版本化。 - 诊断友好:JWT / 中间件 / Nacos / Kestrel 启动期都打印结构化日志(
[Kit.Auth]、[Kit.Pipeline]、[Kit.Nacos]等无斜杠前缀),出错时立刻定位是哪一段配置失败;启动摘要结束后打印“启动诊断完成”分割线。 - 协议透明:v1 SM4-GCM 信封字段命名(
kid/ts/nonce/iv/data/tag)固定,AAD 仅绑定METHOD + kid + ts + nonce + ctxCanonical(不绑 PATH),避开网关 / 反向代理改写 PathBase 导致的 MAC 不一致。
已知限制
- 仅支持 .NET 8.0 + ASP.NET Core 8.0。
- v1 SM 信封强制
Mode=GCM与GcmTagBits=128;CBC 模式仅保留启动期校验占位。 AddGjjSystemInfrastructure在配置缺失Observability:OtlpTraceEndpoint且没有旧SeqHostHTTP兜底时会抛出InvalidOperationException;启用 Nacos/TongNCS 服务注册时,还需要提供Nacos/NacosConfig配置节。- 当前的
SMEncryptionMiddleware.DecryptRequestAsync/DecryptGetAsync标记为async但内部并未使用await,是已知的样式告警(CS1998),不影响行为。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- GJJ.Keystone.Abstractions (>= 4.2.1)
- GJJ.Keystone.AspNetCore.KvStore (>= 4.2.2)
- GJJ.Keystone.Toolkit (>= 4.2.2)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 8.0.0)
- Microsoft.Data.SqlClient (>= 6.1.1)
- nacos-sdk-csharp (>= 1.3.10)
- nacos-sdk-csharp.Extensions.Configuration (>= 1.3.10)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.15.3)
- OpenTelemetry.Extensions.Hosting (>= 1.15.3)
- OpenTelemetry.Instrumentation.AspNetCore (>= 1.15.2)
- OpenTelemetry.Instrumentation.EntityFrameworkCore (>= 1.15.1-beta.1)
- OpenTelemetry.Instrumentation.Http (>= 1.15.1)
- OpenTelemetry.Instrumentation.Runtime (>= 1.15.1)
- OpenTelemetry.Instrumentation.SqlClient (>= 1.15.2)
- Serilog.AspNetCore (>= 8.0.3)
- Serilog.Settings.Configuration (>= 8.0.4)
- Serilog.Sinks.Async (>= 2.1.0)
- Serilog.Sinks.Console (>= 6.0.0)
- Serilog.Sinks.File (>= 7.0.0)
- Serilog.Sinks.OpenTelemetry (>= 4.2.0)
- Serilog.Sinks.Seq (>= 8.0.0)
- StackExchange.Redis (>= 2.8.16)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on GJJ.Keystone.AspNetCore:
| Package | Downloads |
|---|---|
|
GJJ.Keystone.AspNetCore.Redis
[DEPRECATED] 本包已弃用,请改用 GJJ.Keystone.AspNetCore.KvStore。原职责:INonceStore / IJtiBlacklistStore / ISmSessionKeyStore 的 Redis 实现 + jti 双层缓存(L1 + Redis + Pub/Sub) |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.3.5 | 47 | 6/24/2026 |
| 4.3.4 | 49 | 6/23/2026 |
| 4.3.3 | 55 | 6/22/2026 |
| 4.3.2 | 54 | 6/22/2026 |
| 4.3.1 | 56 | 6/17/2026 |
| 4.3.0 | 55 | 6/15/2026 |
| 4.2.7 | 53 | 6/9/2026 |
| 4.2.6 | 60 | 6/9/2026 |
| 4.2.5 | 62 | 6/8/2026 |
| 4.2.4 | 59 | 6/8/2026 |
| 4.2.3 | 50 | 6/8/2026 |
| 4.2.2 | 59 | 6/8/2026 |
| 4.2.1 | 57 | 6/5/2026 |
| 4.2.0 | 66 | 6/5/2026 |
| 4.0.2 | 59 | 6/4/2026 |
| 4.0.1 | 57 | 6/4/2026 |
| 4.0.0 | 59 | 5/22/2026 |
| 3.0.17 | 67 | 5/21/2026 |
| 3.0.16 | 60 | 5/19/2026 |
| 3.0.10 | 90 | 5/13/2026 |