Identity 身份认证模块
Identity 模块是 FreeKit 的"身份与访问"中枢,基于 ASP.NET Core Identity 构建。它不只是一个用户表,而是一组围绕身份主体 IdentityUser 内聚的子域:认证、用户资料、角色、权限、租户、组织架构、设备、双因素、安全密钥、社交登录、个性化。
Identity 不是一个可用单行聚合扩展注册的独立包。当前 Web Host 由组合根同时装配 Core + Infrastructure + HttpApi 三层。
模块边界与子域
| 子域 | 承载的业务能力 | 关键服务接口 |
|---|---|---|
| 认证 | 密码/邮箱验证码登录、注册、注销、刷新 Token、管理员模拟 | IAccountService · ITokenHandler |
| 用户资料 | 跨身份查询、管理员锁定/重置密码、当前用户资料/头像/改密/改用户名 | IUserService · IProfileService |
| 角色 | 角色定义、默认/公开/静态角色、数据范围 | IRoleService |
| 权限 | 权限树、赋权(用户/角色/岗位)、权限检查 | IPermissionService · IPermissionManager |
| 租户 | 租户隔离、切换、邀请成员 | ITenantService |
| 组织架构 | 部门树、岗位、员工档案与调岗 | IOrgUnitService · IPositionService · IEmployeeService |
| 设备 / 2FA | 设备信任、新设备风控、双因素验证 | IUserLoginDeviceManager · ITwoStepVerificationService |
| 安全 | AccessKey、在线用户、Token 吊销、请求日志 | IUserAccessKeyService · IOnlineUserService |
| 社交登录 | OAuth2 绑定/解绑/登录、OpenIddict 客户端 | IOAuth2Service · IOAuth2AdminService |
| 个性化 | 快捷菜单、表格列设置 | IUserShortcutService · ITableColumnSettingService |
横切能力(文件存储、设置系统、通用附件、数据字典)单独文档见 Infrastructure 开发指南。
关系概览
关键边界:没有独立的"用户 CRUD"。 创建用户走注册(
AccountService)、资料修改走ProfileService、员工维度走EmployeeController;UserController仅提供只读查询。用户生命周期被有意拆分到不同职责边界,见 领域能力指南。
快速开始
1. 在 Host 组合根注册三层
// Program.cs
builder.Services.AddModule<IdentityModuleStartup>(
"identity",
builder.Configuration);
// E.Modules 已包含 identity-inf -> IdentityInfrastructureModuleStartup。
// Web Host 将 identity 映射替换为 HttpApi,Core 则已在上面显式注册。
var hostModules = new Dictionary<string, Type>(E.Modules, StringComparer.OrdinalIgnoreCase)
{
["identity"] = typeof(IdentityHttpApiModuleStartup)
};
builder.UseFreeKit(
moduleTypeMap: hostModules,
extraAssemblies: new[]
{
typeof(Program).Assembly,
typeof(IdentityModuleStartup).Assembly
});
三层职责如下:
| 启动类 | 当前职责 |
|---|---|
IdentityModuleStartup | Identity Core:Identity/FreeSql、授权处理器、领域与应用服务依赖、租户中间件和核心表初始化 |
IdentityInfrastructureModuleStartup | 文件、设置、通用附件等基础设施,以及其实体映射和设置定义初始化 |
IdentityHttpApiModuleStartup | HTTP 接入层:Controller 所在程序集、SignalR 与 /hubs/onlineuser |
UseFreeKit(...) 会调用映射中各启动类的 ConfigureServices;构建应用后,主 Host 还通过 app.ConfigureModules() 执行各模块的 Configure。完整组合以 src/Services/Host/FreeKit.Host/Program.cs 和 src/Services/Host/FreeKit.DI/E.cs 为准。
2. 配置数据库
{
"ConnectionStrings": {
"DefaultDB": "0",
"MySql": "Data Source=localhost;Port=3306;User ID=<DB_USER>;Password=<DB_PASSWORD>;Initial Catalog=freekit;Charset=utf8mb4",
"Redis": "localhost:6379,password=<REDIS_PASSWORD>,defaultDatabase=0"
}
}
3. 启动服务
dotnet run --project src/Services/Host/FreeKit.Host
4. 访问 Swagger
https-dev profile 监听 https://localhost:7000(HTTP 为 http://localhost:5000)。主 Compose 设置 ASPNETCORE_PATHBASE=/kit_api,此时访问:
- Swagger:
https://localhost:7000/kit_api/swagger - Identity API:
https://localhost:7000/kit_api/api/identity/... - SignalR:
https://localhost:7000/kit_api/hubs/onlineuser
直接使用 launch profile 且未设置 ASPNETCORE_PATHBASE 时,路径中没有 /kit_api,例如 https://localhost:7000/swagger。
架构概览
设计要点速览
角色与数据范围
角色是权限的容器,本身不定义权限。IdentityRole 区分默认角色(注册自动分配)、公开角色(其他用户可见)、静态角色(内置不可删)。DataScope 控制角色可触及的数据边界:
| 值 | 说明 |
|---|---|
All | 全部数据 |
OrgWithChild | 本部门及子部门 |
Org | 仅本部门 |
Self | 仅自己 |
权限树与解析
权限点通过 PermissionType 分层:Folder(目录) / Menu(菜单) / Element(按钮) / Api(后端接口)。PermissionManager.InitPermissionAsync() 会扫描控制器 [Authorize] / [KitAuthorize] 并同步权限树,但主 Host 当前只在 #if DEBUG 的 MigrationStartAsync() 路径调用它;Release / 生产启动不会自动同步。生产权限变更必须进入显式迁移或受控初始化流程。解析时查 PermissionGrant 的 U/R/P(用户/角色/岗位)三来源合并判定(详见 领域能力指南 的“权限”子域)。
租户隔离
多租户通过中间件 IdentityTenantResolver 在请求期确定当前租户,解析优先级为 X-Tenant-Id 请求头 > JWT tenant_id 声明。切换租户会重新签发 Token 并写入新 tenant_id。
设备与双因素
设备指纹基于 UserAgent 的 SHA256 哈希(IP 变化不影响识别)。受信设备 + 无 2FA 直接放行;未受信设备按 Device.NewDeviceMode(notify/verify)决策;开启 2FA 始终要求验证码。信任默认 180 天(Device:TrustExpireDays)后过期。
持久化
Identity 的表包括 identity_user、identity_role、identity_tenant、identity_org_unit、identity_permission、identity_user_access_key、identity_user_login_device 等。IdentitySchemaMigrator 在所有构建中执行兼容迁移;大范围 SyncStructure(...) 与 SeedData() 只位于 #if DEBUG,不能把 Debug 自动同步当作生产迁移方案。完整实体清单见 src/Services/Identity/FreeKit.Identity/Models。
源码定位
src/Services/Host/FreeKit.Host/Program.cs:Web Host 的真实三层组合与/kit_api管道src/Services/Host/FreeKit.DI/E.cs:共享模块映射,包含identity-infsrc/Services/Identity/FreeKit.Identity/IdentityModuleStartup.cs:Core 注册与初始化src/Services/Identity/FreeKit.Identity.Infrastructure/IdentityInfrastructureModuleStartup.cs:Infrastructure 注册与初始化src/Services/Identity/FreeKit.Identity.HttpApi/IdentityHttpApiModuleStartup.cs:HTTP/SignalR 接入