MiniAuth 一个轻量 ASP.NET Core Identity Web 后台管理中间插件
「一行代码」为「新、旧项目」 添加 Identity 系统跟用户、权限管理网页后台系统
开箱即用,避免打掉重写或是严重耦合情况
Github:https://github.com/mini-software/MiniAuth , Gitee: https://gitee.com/shps951023/MiniAuth
特点
- 兼容 : 支持 .NET identity Based on JWT, Cookie, Session 等
- 简单 : 拔插设计,API、SPA、MVC、Razor Page 等开箱即用
- 支持多数据库 : 支持 Oracle, SQL Server, MySQL 等 EF Core
- 非侵入式 : 不影响现有数据库、项目结构
- 多平台 : 支持 Linux, macOS 环境
安装
从NuGet安装套件
快速开始
在 Startup 添加一行代码 services.AddMiniAuth()
并运行项目,例子:
public class Program{ public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddMiniAuth(); // <= ❗❗❗ var app = builder.Build(); app.Run(); }}
接着访问管理网页,Link 为 http(s)://yourhost/miniauth/index.html
,预设 admin 管理账号为 admin@mini-software.github.io
密码为E7c4f679-f379-42bf-b547-684d456bc37f
(请记得修改密码),即可管理你的 Identity 用户、角色、端点。
在需要权限管理的类别或方法上加上[Authorize]
或是角色管控[Authorize(Roles ="角色")]
,假设没登入返回 401 状态, 没权限返回 403 状态。
MiniAuth Cookie Identity
MiniAuth 预设为单体 Coookie Based identity,如前后端分离项目请更换 JWT 等 Auth。
MiniAuth JWT Identity
只需要简单指定 AuthenticationType 为 BearerJwt
builder.Services.AddMiniAuth(options:(options) =>{ options.AuthenticationType = MiniAuthOptions.AuthType.BearerJwt;});
请记得自定义 JWT Security Key,如:
builder.Services.AddMiniAuth(options: (options) =>{ options.JWTKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("6ee3edbf-488e-4484-9c2c-e3ffa6dcbc09"));});
获取用户 token 方式
前端 Javascript XHR 例子
var data = JSON.stringify({"username":"admin@mini-software.github.io","password":"E7c4f679-f379-42bf-b547-684d456bc37f","remember": false});var xhr = new XMLHttpRequest();xhr.withCredentials = true;xhr.addEventListener("readystatechange", function() { if(this.readyState === 4) { console.log(this.responseText); }});xhr.open("POST","http://yourhost/miniauth/login");xhr.setRequestHeader("Content-Type","application/json");xhr.send(data);
返回结果
{"ok": true,"code": 200,"message": null,"data": {"tokenType":"Bearer","accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYW1lIjoiYWRtaW5AbWluaS1zb2Z0d2FyZS5naXRodWIuaW8iLCJyb2xlIjoibWluaWF1dGgtYWRtaW4iLCJzdWIiOiJhZG1pbkBtaW5pLXNvZnR3YXJlLmdpdGh1Yi5pbyIsIm5iZiI6MTcxODIwNDg5NSwiZXhwIjoxNzE4MjA1Nzk1LCJpYXQiOjE3MTgyMDQ4OTUsImlzcyI6Ik1pbmlBdXRoIn0._-DQ_rcbeju8_nrK2lD5we0rre04_xdDZNF6NhM0Rg0","expiresIn": 900 }}
将 accessToken 保存在 localstorage 或是 cookie 内,呼叫你的 [Authorize] api 时设定 Header Authorization : Bearer + 空格 + accessToken
,系统会自动验证。
举例:
var xhr = new XMLHttpRequest();xhr.withCredentials = true;xhr.addEventListener("readystatechange", function() { if(this.readyState === 4) { console.log(this.responseText); }});xhr.open("GET","http://yourhost:5014/your/api");xhr.setRequestHeader("Authorization","Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYW1lIjoiYWRtaW5AbWluaS1zb2Z0d2FyZS5naXRodWIuaW8iLCJyb2xlIjoibWluaWF1dGgtYWRtaW4iLCJzdWIiOiJhZG1pbkBtaW5pLXNvZnR3YXJlLmdpdGh1Yi5pbyIsIm5iZiI6MTcxODIwNDg5NSwiZXhwIjoxNzE4MjA1Nzk1LCJpYXQiOjE3MTgyMDQ4OTUsImlzcyI6Ik1pbmlBdXRoIn0._-DQ_rcbeju8_nrK2lD5we0rre04_xdDZNF6NhM0Rg0");xhr.send();
设定过期时间
options.TokenExpiresIn = 30 * 60;
单位为秒,预设30分钟,另外注意 .NET JWT ClockSkew JwtBearerOptions 预设要额外加上5分钟 原因
刷新 Refresh Token API (JWT)
API : /MiniAuth/refreshToken
Body:
{"refreshToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYmYiOjE3MTg1MjIxOTEsImV4cCI6MTcxODUyMzk5MSwiaWF0IjoxNzE4NTIyMTkxLCJpc3MiOiJNaW5pQXV0aCJ9.HYBWrM2suDiM4OG0FSlXhNgktZIG9l3ufmIAnwZiIoU"}
Header:
Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW5AbWluaS1zb2Z0d2FyZS5naXRodWIuaW8iLCJyb2xlIjoibWluaWF1dGgtYWRtaW4iLCJzdWIiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYmYiOjE3MTg1MjIxOTEsImV4cCI6MTcxODUyNTc5MSwiaWF0IjoxNzE4NTIyMTkxLCJpc3MiOiJNaW5pQXV0aCJ9.rgAgsziAdLqOC9NYra-M9WQl8BJ99sRdfzRKNkMz9dk
过期时间为MiniAuthOptions.TokenExpiresIn / 2
,预设30分钟
设定、选项、自定义
预设模式
- MiniAuth 预设模式为IT Admin 集中用户管理,用户注册、密码重置等操作需要 Admin 权限账号操作,预设 Role = miniauth-admin
关闭 MiniAuth Login
如果你只想用自己的登录逻辑、页面、API,可以指定登录路径,关闭开关
// 放在 service 注册之前builder.Services.AddMiniAuth(options: (options) =>{ options.LoginPath ="/Identity/Account/Login"; options.DisableMiniAuthLogin = true;});
自定义预设的 SQLite Connection String
builder.Services.AddMiniAuth(options: (options) =>{ options.SqliteConnectionString ="Data Source=miniauth_identity.db";});
自定义数据库、用户、角色
MiniAuth 系统预设使用 SQLite EF Core、IdentityUser、IdentityRole开箱即用
如果需要切换请在app.UseMiniAuth
泛型指定不同的数据库、自己的用户、角色类别。
app.UseMiniAuth<YourDbContext, YourIdentityUser, YourIdentityRole>();
登录、用户验证
非 ApiController 预设登录导向 login.html 页面 (判断方式Headers["X-Requested-With"] =="XMLHttpRequest" 或是 ApiControllerAttribute)
ApiController 的 Controller 预设不会导向登录页面,而是返回 401 status code
自定义前端
- 管理后台前端在
/src/Frontend_Identity
主体使用 Vue3 + Vite,使用 npm run build 后即可更新 miniauth 的 UI - 登录页面不想使用 miniauth 预设, mvc可以使用 identity 自带的Scaffolded Login.cshtml ,或是更改 miniauth 前端的 login.html, js, css
自定路由前缀
builder.Services.AddMiniAuth(options: (options) =>{ options.RoutePrefix ="YourName";});
预设 RoutePrefix 为 MiniAuth
。
登录API (JWT)
API:/MiniAuth/login
Body:
{"username":"admin@mini-software.github.io","password":"E7c4f679-f379-42bf-b547-684d456bc37f","remember":false}
Response:
{"ok": true,"code": 200,"message": null,"data": {"tokenType":"Bearer","accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW5AbWluaS1zb2Z0d2FyZS5naXRodWIuaW8iLCJyb2xlIjoibWluaWF1dGgtYWRtaW4iLCJzdWIiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYmYiOjE3MTg1MjIxOTEsImV4cCI6MTcxODUyNTc5MSwiaWF0IjoxNzE4NTIyMTkxLCJpc3MiOiJNaW5pQXV0aCJ9.rgAgsziAdLqOC9NYra-M9WQl8BJ99sRdfzRKNkMz9dk","expiresIn": 3600,"refreshToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYmYiOjE3MTg1MjIxOTEsImV4cCI6MTcxODUyMzk5MSwiaWF0IjoxNzE4NTIyMTkxLCJpc3MiOiJNaW5pQXV0aCJ9.HYBWrM2suDiM4OG0FSlXhNgktZIG9l3ufmIAnwZiIoU" }}
注册
请使用 ASP.NET Core Identity 自带的注册API跟页面
忘记密码
请使用 ASP.NET Core Identity 自带的注册API跟页面
获取用户信息
请使用 ASP.NET Core Identity 自带的注册API跟页面
注意事项
注意顺序
请将 UseMiniAuth 放在路由生成之后,否则系统无法获取路由数据作权限判断,如 :
app.UseRouting();app.UseMiniAuth();
请添加 Role 规则
请添加AddRoles<IdentityRole>()
,否则[Authorize(Roles ="权限")]
不会生效
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddRoles<IdentityRole>() // ❗❗❗ .AddEntityFrameworkStores<ApplicationDbContext>();
应用在现有的 identity 项目,自定义逻辑
把 AddMiniAuth autoUse 关闭,将 UseMiniAuth 并在泛型参数换上自己的 IdentityDBContext、用户、权限认证,放在自己的 Auth 之后,例子:
public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddRoles<IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>(); builder.Services.AddControllersWithViews(); builder.Services.AddMiniAuth(autoUse: false); // <= ❗❗❗ var app = builder.Build(); app.UseMiniAuth<ApplicationDbContext, IdentityUser, IdentityRole>(); // <= ❗❗❗ app.MapControllerRoute( name:"default", pattern:"{controller=Home}/{action=Index}/{id?}"); app.MapRazorPages(); app.Run(); }
能切换使用自己的用户、角色、DB、Identity 逻辑。
分布式系统
- 数据库来源请换成 SQL Server、MySQL、PostgreSQL 等数据库
- 建议更换 JWT 等 auth 方式