角色认证,中间件,权限判断学习和理解

114 阅读3分钟

这篇太杂了,权当学习笔记。有好几个知识点,角色认证,自定义中间件,权限核心判断,以及链式编程,隐式转换等等。

还是用代码来说事吧。

www.cnblogs.com/whuanle/p/1…

www.cnblogs.com/whuanle/p/1…

img

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…

www.cnblogs.com/ysmc/p/1651…

帮助理解文章:blog.csdn.net/qq_39173779…

blog.csdn.net/qq_41872328…