这篇太杂了,权当学习笔记。有好几个知识点,角色认证,自定义中间件,权限核心判断,以及链式编程,隐式转换等等。
还是用代码来说事吧。
1 第一步运行加载所有角色和用户信息
全部存在内存里面 就是所有人的访问链接都在内存里
2 第二步 登录
检查角色是否存在,获取用户和角色信息,把角色和用户信息封装到token里面
3 第三 中间件里判断
3.1 第一步
检查用户和角色是否存在内存集合里 【数据库里检查用户是否还存在】
3.2 第二步
用用户和角色去内存里拿出用户有拥有的访问链接 【数据库里查询用户所有访问链接】【权限列表:添加,修改,删除,查询,导出,导入,打印】
3.3 第三步
用当前的访问的链接判断是否在用户拥有的链接里 【当前访问的链接与从数据库里查询出来的链接是否匹配】【通过属性获取,然后与权限列表判断是否有】
用A类去返回B类
public class A
{
private readonly B BModel;
/// <summary>
/// 构造函数里实例化B
/// </summary>
public A()
{
BModel = new B();
}
/// <summary>
/// 变成链式并填充B类数据
/// </summary>
/// <param name="name"></param>
/// <param name="age"></param>
/// <returns></returns>
public A CreateFillB(string name,int age)
{
BModel.Name = name;
BModel.Age = age;
return this;
}
/// <summary>
/// 返回B
/// </summary>
/// <returns></returns>
public B Build()
{
return BModel;
}
}
public class B
{
public string Name { get; set; }
public int Age { get; set; }
}
通过实例A类,调用Build()方法就可以获得B类
var authOptions = new AuthBuilder()
.Security("aaaafsfsfdrhdhrejtrjrt", "ASPNETCORE", "ASPNETCORE")
.Jump("accoun/login", "account/error", false, false)
.Time(TimeSpan.FromMinutes(20))
.InfoScheme(new Auth.Models.AuthenticateScheme
{
TokenEbnormal = "Login authentication failed!",
TokenIssued = "Login authentication failed!",
NoPermissions = "Login authentication failed!"
}).Build();
services.AddRoleService(authOptions);
隐式转换
这是C#中定义隐式转换的语法。在类或结构体中,可以使用 operator 关键字来定义自定义的隐式类型转换操作符。语法格式如下:
public static implicit operator 目标类型(源类型 变量名)
{
// 转换操作
}
其中,implicit 为隐式类型转换操作符关键字,目标类型 是要转换成的类型,源类型 变量名 是需要进行转换的变量。
例如,可以在一个自定义的类中实现隐式转换,将该类对象转换为 int 类型的值。示例代码如下:
public class MyInt
{
private int value;
public MyInt(int val)
{
value = val;
}
public int Value
{
get { return value; }
set { this.value = value; }
}
public static implicit operator int(MyInt myInt)
{
return myInt.Value;
}
}
// 使用隐式类型转换将 MyInt 对象转换为 int 类型
MyInt myInt = new MyInt(10);
int i = myInt; // 等同于 int i = myInt.Value;
需要注意的是,隐式类型转换只能在两个类型存在继承或兼容关系时才能进行,并且如果多个隐式类型转换操作符重载了相同的类型,则编译器无法确定选择哪一个,从而导致编译错误。
中间件核心
public RoleMiddleware(RequestDelegate next,可以添加哦)//这里同样可以增加东西
{
_next = next;
}
public async Task Invoke(HttpContext context, IRoleEventsHadner roleEventsHadner)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
//核心代码
var endpoint = context.GetEndpoint();
// IMPORTANT: Changes to authorization logic should be mirrored in MVC's AuthorizeFilter
var authorizeData = endpoint?.Metadata.GetOrderedMetadata<IAuthorizeData>() ?? Array.Empty<IAuthorizeData>();
// 如果没有 [Authorize] 就不需要拦截 判断【拦截属性存在和个数】
if (authorizeData == null || authorizeData.Count == 0)
{
await _next(context);
return;
}
// 如果有 [AllowAnonymous],那也不需要拦截 判断属性【内容】
if (endpoint?.Metadata.GetMetadata<IAllowAnonymous>() != null)
{
await _next(context);
return;
}
//核心代码
_roleEventsHadner = roleEventsHadner;//角色
// 进来时
var result = await AuthorizationService(context);// 进一步判断
if (result == false)
{
context.Response.StatusCode = StatusCode;
context.Response.Headers.Add("WWW-Authenticate", new Microsoft.Extensions.Primitives.StringValues(loginfailed));
return;
}
await _next(context);
return;
}
使用
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
// app.UseMiddleware<RoleMiddleware>();原始用法
app.UseRoleMiddleware();//替换哦原来这么简单
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
封装一下
/// <summary>
///
///封装哦
/// </summary>
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseRoleMiddleware(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware<RoleMiddleware>();
}
}
参考文章:blog.csdn.net/qq_41872328…
帮助理解文章:blog.csdn.net/qq_39173779…