首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

MiniAuth 一个轻量 ASP.NET Core Identity Web 后台管理中间插件

编程知识
2024年07月21日 19:46

MiniAuth 一个轻量 ASP.NET Core Identity Web 后台管理中间插件

「一行代码」为「新、旧项目」 添加 Identity 系统跟用户、权限管理网页后台系统

开箱即用,避免打掉重写或是严重耦合情况

Github: https://github.com/mini-software/MiniAuth , Gitee: https://gitee.com/shps951023/MiniAuth

Image 1 Image 2
Image 3 Image 4

特点

  • 兼容 : 支持 .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 方式
From:https://www.cnblogs.com/ITWeiHan/p/18314934
本文地址: http://shuzixingkong.net/article/261
0评论
提交 加载更多评论
其他文章 Java JVM——13. 垃圾回收算法
1.生存还是死亡? 在堆里存放着几乎所有的 Java 对象实例,在 GC 执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC 才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们称为垃圾标记阶段。 那么在 JVM 中究竟是如何标记
Java JVM——13. 垃圾回收算法 Java JVM——13. 垃圾回收算法 Java JVM——13. 垃圾回收算法
自学考试(北邮)计算机专业毕业总结
本文目的 2024年是北京自学考试专业过渡期,恰好赶在过渡期前完成了专业的全部课程,于是2024上半年开始毕业论文与设计并完成了答辩,赶在收到毕业证这天总结一下,给后续北邮自考生一点参考,给自己这5年的努力作个总结。 毕业要求所学专业的所有笔试、实践科目、论文成绩均合格,其中笔试、实践是比较常规的考
自学考试(北邮)计算机专业毕业总结 自学考试(北邮)计算机专业毕业总结 自学考试(北邮)计算机专业毕业总结
Ubuntu16.04升级openssh-9.8p1
7月1日OpenSSH官方发布安全更新,忙着处理的同时记录一下升级过程。 系统环境 root@NServer:~# cat /proc/version Linux version 3.4.113-sun8i (root@test) (gcc version 5.5.0 (Linaro GCC 5.5
Ubuntu16.04升级openssh-9.8p1 Ubuntu16.04升级openssh-9.8p1 Ubuntu16.04升级openssh-9.8p1
salesforce零基础学习(一百四十)Record Type在实施过程中的考虑
本篇参考: salesforce 零基础学习(二十九)Record Types简单介绍 https://help.salesforce.com/s/articleView?id=sf.customize_recordtype_considerations.htm&amp;type=5 https:/
前端快速处理几十万条数据的方式?
在前端处理大量数据时,可以采用以下几种方式来提高处理速度和性能: 数据分页:将数据分成多个页面,并按需加载。只加载当前页面的数据,而不是一次性加载全部数据。这可以减少初始加载时间和内存占用,并提高用户体验。 虚拟滚动:对于需要展示大量列表或表格数据的情况,可以使用虚拟滚动技术。虚拟滚动只渲染可见区域
网络基础 Modbus协议学习总结
协议简介 Modbus协议,首先从字面理解它包括Mod和Bus两部分,首先它是一种bus,即总线协议,总线就意味着有主机,有从机,这些设备在同一条总线上。 Modbus支持单主机,多个从机,最多支持247个从机设备。关于Mod,因为这种协议最早被用在PLC控制器中,准确的说是Modicon公司的PL
网络基础 Modbus协议学习总结 网络基础 Modbus协议学习总结 网络基础 Modbus协议学习总结
关键点检测(1)——标注关键点检测数据(labelme和CVAT)
关键点检测,作为计算机视觉领域的重要分支,广泛应用于人体姿态估计、面部表情识别、手部动作分析等多个场景。其核心在于从图像中准确检测并定位特定的关键点位置。然而,高效的模型训练离不开大量高质量的标注数据。本文将详细介绍关键点检测数据的标注方法,包括标注工具的选择、标注流程以及注意事项,帮助自己深入理解
关键点检测(1)——标注关键点检测数据(labelme和CVAT) 关键点检测(1)——标注关键点检测数据(labelme和CVAT) 关键点检测(1)——标注关键点检测数据(labelme和CVAT)
AI时代你应聚焦的领域在哪里
随着AI的飞速发展,把我们带到了一个全新的时代。每个人都应该积极拥抱AI,让AI给我们提效。那不同的人群应该聚焦在哪里呢?
AI时代你应聚焦的领域在哪里