Jeff.Utility 2.1.1

dotnet add package Jeff.Utility --version 2.1.1
                    
NuGet\Install-Package Jeff.Utility -Version 2.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Jeff.Utility" Version="2.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Jeff.Utility" Version="2.1.1" />
                    
Directory.Packages.props
<PackageReference Include="Jeff.Utility" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Jeff.Utility --version 2.1.1
                    
#r "nuget: Jeff.Utility, 2.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Jeff.Utility@2.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Jeff.Utility&version=2.1.1
                    
Install as a Cake Addin
#tool nuget:?package=Jeff.Utility&version=2.1.1
                    
Install as a Cake Tool

概述

本框架用于 Asp.Net Core WebApi 项目,核心是开箱即用的通用权限服务。框架可以在单个的 App 中使用,也可用作认证网关。 JeffUtility 本身只是一个类库,既适用于单体程序,也可用于多项目方案。

[[快速开始]]
[[内置 Api]]
[[权鉴网关]]
[[其他]]

快速开始

// 添加 JeffUtility 数据库
builder.Services.AddDbContext<JeffUtilityContext>(opt => opt.UseMySql(
    builder.Configuration.GetConnectionString("mysql"), ServerVersion.Parse("8.0.25"),
    option =>
    {
        option.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
        option.EnableRetryOnFailure();
    })
);

// 添加 JeffUtility 服务
builder.Services.AddJeffUtility(opt =>
{
    //首次使用时通过 EnsureCreated 创建数据库, 创建后可删除或置为 false
    opt.Database.DbContextEnsureCreated = true;

    //内置的权限管理API,比如用户管理,角色管理等
    opt.Auth.ShowAuthManageAPI();

    //启用本地权鉴默认服务
    opt.Auth.UseLocalAuth(jwt =>
    {
        jwt.Secret = "Your_Json_Web_Tokens_Private_Key";
        jwt.Expire = 1_000_000;
    });

    //定义返回对象格式,会覆盖默认的返回格式
    //opt.WebApi.UseResponseBody(b => new { code = b.Code == 200 ? 0 : 1 });

    //定义验证码发送委托,用于发送短信验证码
    //opt.Auth.SendSMSCode = Aliyun_SMSHandler.SendSMSCode;

    //多租户
    //opt.Auth.MultiTenant = true;

    //作为权鉴网关使用
    //opt.Auth.UseAuthGateway(jwt =>
    //{
    //    jwt.Secret = "Your_Json_Web_Tokens_Private_Key";
    //    jwt.Expire = 1_000_000;
    //});
});

//...

var app = builder.Build();

app.InitJeffUtility();   //初始化权限服务

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    //app.UsePathBase("/api");

    app.UseSwaggerUI(c =>
    {
        //设置 Swagger 的路径前缀
        c.SwaggerEndpoint("/swagger/JeffUtility/swagger.json", "Jeff Utility");
        c.SwaggerEndpoint("/swagger/MyApi/swagger.json", "My WebApi");
        c.DocExpansion(DocExpansion.None);
    });
}

 

Jeff.Repository

Jeff Utility 中引用了 Jeff.Repository,配置示例如下。具体使用可参考 Jeff.Repository 文档。

builder.Services.Configure<RepositoryConfig>(cfg =>
{
    cfg.PrimaryKeyAlgo = PKAlgo.SnowFlake;

    cfg.SoftDeleteProperty = "IsDeleted";
    cfg.UpdateTimeProperty = "UpdateTime";
    cfg.CreateTimeProperty = "CreateTime";
    cfg.VersionProperty = "Version";
});

 

Swagger XML 注释

Jeff Utility 内置了一些 WebAPI,通过以下方式添加 Swagger 注释。注意将其中的 1.x.x 换成实际的版本号。

<ItemGroup>
  <Content Include="$(NuGetPackageRoot)\jeff.utility\1.x.x\lib\net8.0\*.xml" Visible="false" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

 

数据库迁移

以上代码通过 EFCore 的 EnsureCreated 模式生成数据库。EnsureCreated 模式适合数据库初始创建的场景,若数据库中已有表,可使用 Migration 模式。

  1. 修改上面的数据库配置

     //配置数据库连接
     opt.Db.SetDbContext(opt =>
     {
       opt.UseMySql(builder.Configuration.GetConnectionString("mysql"), ServerVersion.Parse("8.0.25"), c =>
       {
     	c.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
     	c.EnableRetryOnFailure();
     	c.MigrationsAssembly("Your_WebApi_Assembly"); //设置你的WebApi为迁移程序集
       });
     }); 
    
     //删除 EnsureCreated 或赋值为false,默认false
     //opt.Db.DbContextEnsureCreated = false;
    
  2. 创建迁移

     dotnet ef migrations add JeffUtilityInit --context JeffUtilityContext
    
  3. 迁移创建成功后,生成数据表

     dotnet ef database update --context JeffUtilityContext
    

    本框架暂只支持 EF Core。

 

内置 Api

管理 API

管理相关API在配置中,通过 opt.Auth.ShowAuthManageAPI();暴露接口。

模块 Http Method 路径 说明
Signup POST /signup/bysms 用户注册
GET /signup/send-sms 发送验证码,需配置验证码委托 SendSMSCode
System GET /system/clear-caches 释放所有缓存
User GET /user 查询用户列表
POST /user 新增用户
GET /user/{userId} 查询单个用户
DELETE /user/{userId} 删除用户
PUT /user/{userId} 更新用户
PUT /user/{userId}/role 更新用户角色
CurrentUser PUT /current-user/password 修改当前用户密码
GET /current-user 获取当前用户信息
Permission GET /permission 查询权限清单
POST /permission 新增权限
PUT /permission 批量编辑权限
PUT /permission/{id} 编辑权限
DELETE /permission/{id} 删除权限
PermissionPattern GET /permission-pattern/api 查询权限关联的API模板列表
POST /permission-pattern/api 添加权限关联的API模板
DELETE /permission-pattern/api/{id} 删除权限关联的API模板
PUT /permission-pattern/api/{id} 更新权限直接关联的API模板
GET /permission-pattern/route 查询权限关联的Route模板列表
POST /permission-pattern/route 添加权限关联的Route模板
DELETE /permission-pattern/route/{id} 删除权限关联的Route模板
PUT /permission-pattern/route/{id} 更新权限直接关联的Route模板
Role GET /role 查询角色列表
POST /role 新增角色
PUT /role 批量更新角色
PUT /role/{roleId} 更新角色
POST /role/set-permission 给角色分配权限
RolePattern GET /role-pattern/api/common 查询一般角色关联的API模板列表
POST /role-pattern/api/common 添加一般角色关联的API模板
DELETE /role-pattern/api/common/{id} 删除一般角色关联的API模板
PUT /role-pattern/api/common/{id} 更新一般角色直接关联的API模板
GET /role-pattern/api/anonymous 查询匿名角色关联的API模板列表
POST /role-pattern/api/anonymous 添加匿名角色关联的API模板
DELETE /role-pattern/api/anonymous/{id} 删除匿名角色关联的API模板
PUT /role-pattern/api/anonymous/{id} 更新匿名角色直接关联的API模板
GET /role-pattern/api/authenticated 查询登录用户角色关联的API模板列表
POST /role-pattern/api/authenticated 添加登录用户角色关联的API模板
DELETE /role-pattern/api/authenticated/{id} 删除登录用户角色关联的API模板
PUT /role-pattern/api/authenticated/{id} 更新登录用户角色直接关联的API模板
GET /role-pattern/route/common 查询一般角色关联的Route模板列表
POST /role-pattern/route/common 添加一般角色关联的Route模板
DELETE /role-pattern/route/common/{id} 删除一般角色关联的Route模板
PUT /role-pattern/route/common/{id} 更新一般角色直接关联的Route模板
Tenant GET /tenant 查询所有租户
POST /tenant 新增租户信息
PUT /tenant/{id} 租户编辑
DELETE /tenant/{id} 租户删除

认证 API

模块 Http Method 路径 说明
Login POST /login/bypwd 密码登录
POST /login/bysms 手机验证码登录,前提验证码委托 SendSMSCode
GET /login/send-sms 发送验证码
AuthGateway GET /auth-gateway/auth api权鉴,限网关使用

 

权鉴网关

  • 权鉴网关为其他API提供权限认证
    • 负责 接口权鉴验证、拦截。验证失败,返回401/403,并拦截请求。验证成功,继续执行API。
    • 负责 提供用户信息。网关将当前用户信息写入请求头,API直接读取请求头获取当前用户。
  • 权鉴网关基于 ngx_http_auth_request_module 实现。

 

1. 网关端

若配置为权鉴网关,需要配置 JWT。 配置后,系统会暴露网关接口: Get /auth-gateway/auth,供 nginx 调用。

builder.Services.AddJeffUtility(opt =>
{
  //配置为权鉴网关
  opt.Auth.AsAuthGateway(jwt =>
  {
	jwt.Secret = "Your_Json_Web_Tokens_Private_Key";
	jwt.Expire = 1_000_000;
  });
}

 

2. nginx 配置

nginx 需要支持 ngx_http_auth_request_module。在 nginx 为后端服务配置 auth_request,示例 :

server {
  listen       12345;
  server_name  "";
	
  # 权鉴服务
  location /auth/ {
	internal;
	proxy_pass http://localhost:7701/auth-gateway/auth/;     # 指定权鉴接口
	proxy_pass_request_body off;
	
	# 写入权鉴请求,用以权限验证
	proxy_set_header X-Request-Method $request_method;       # GET/POST
	proxy_set_header X-Request-URI $request_uri;             # /system-manage/user/123
	proxy_set_header X-Current-Location $current_location;   # /system-manage
  }

  # 后端服务
  location /system-manage/ {
	set $current_location "/system-manage";   # 当前 location 的路径
	
	auth_request /auth;    # 权鉴请求接口
	
	# 读取权鉴响应,写入变量
	auth_request_set $user_id $upstream_http_x_user_id;
	auth_request_set $user_phone $upstream_http_x_user_phone; 
	auth_request_set $tenant_id $upstream_http_x_tenant_id;          # 租户适用
	auth_request_set $tenant_code $upstream_http_x_tenant_code;      # 租户适用
	auth_request_set $refresh_token $upstream_http_x_refresh_token;  # 刷新token
	
	# 读取变量,写入请求头,传给后端
	proxy_set_header X-User-Id $user_id;
	proxy_set_header X-User-Phone $user_phone;
	proxy_set_header X-Tenant-Id $tenant_id;
	proxy_set_header X-Tenant-Code $tenant_code;
	
	# 读取变量,写入响应头,传给前端
	add_header X-Refresh-Token $refresh_token;
		
	proxy_pass http://localhost:7702/;
	proxy_set_header   Host  $host;
  }
	
  # error_page  404              /404.html;
	
  # redirect server error pages to the static page /50x.html
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
	root   /usr/share/nginx/html;
  }
	
  # error_page 401 =401 /auth/401;   # 替换状态码,=与401之间没有空格,200会覆盖原有的code
}

 

3. AppCode

  • 多应用场景,以AppCode作为应用标识。单应用忽视该字段。
  • 多应用场景,前端在调用API时,需要在 Header 中添加 X-App-Code,用以标识应用。比如 X-App-Code: SystemManage
  • 数据表 uti_appservice 管理应用清单。其他表中的 AppCode 字段与之关联,包含 uti_anonymousapi, uti_authenticatedapi, uti_permission, uti_roleapi, uti_roleroute。  

其他

默认消息

支持默认消息配置。在 appsettings.json 中配置

// 状态码的默认消息
"StatusCodeMessage": {
  "200": "success",
  "400": "the argument is error.",
  "401": "身份验证失败",
  "403": "用户无相关权限",
  "404": "目标不存在",
  "500": "程序异常"
},

// 异常类型的默认状态和消息
"ExceptionMessage": {
  "System.ArgumentOutOfRangeException": "400 参数异常",
  "System.ArgumentNullException": "400 参数异常",
  "System.ArgumentException": "400 参数异常",
  "System.InvalidOperationException": "400 非法操作",
  "Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException": "500 数据冲突",
  "Microsoft.EntityFrameworkCore.DbUpdateException": "500 数据保存失败",
  "System.Data.Common.DbException": "500 数据库操作异常",
  "System.IO.DirectoryNotFoundException": "404 目标不存在",
  "System.IO.FileNotFoundException": "404 文件不存在",
  "System.Exception": "500 发现异常"
}
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.1 143 5/19/2025
2.1.0 215 5/16/2025
2.0.0 152 5/8/2025
1.9.9 146 5/7/2025
1.9.8 154 4/29/2025
1.9.4 159 4/28/2025
1.9.1 134 4/27/2025
1.9.0 138 4/27/2025
1.8.5 124 4/25/2025
1.8.4 135 4/25/2025
1.8.0 160 4/24/2025
1.7.9 170 4/23/2025
1.7.6 198 4/17/2025
1.7.1 133 4/11/2025
1.7.0 135 3/27/2025
1.6.7 469 3/26/2025
1.6.0 104 12/25/2024
1.5.8 108 12/21/2024
1.5.7 112 12/20/2024
1.5.6 98 12/20/2024
1.5.5 109 12/19/2024
1.4.0 96 12/10/2024
1.1.30 118 10/7/2024
1.1.20 125 9/18/2024