.net core 3.1 鉴权 授权 基础模型和运行机制及中间件管道探秘

交流QQ群:555913397
有什么问题可以加群大家一起交流

创建自定义的cookie鉴权 授权 管道…相信很多人都没搞清楚,这里为大家揭开心中的疑惑.废话不多说,上代码…

1.创建一个自定义的鉴权 授权 签发Ticket的Hanlder

 这里实现登录签发Ticket  退出登录销毁Ticket 鉴权 授权等管理
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;

namespace CoreMvc.Utinity.Authentications
{
    public class CoreMvcAuthenticationHandler : IAuthenticationHandler, IAuthenticationSignInHandler, IAuthenticationSignOutHandler
    {
        public AuthenticationScheme Scheme { get; private set; }
        protected HttpContext Context { get; private set; }

        /// 
        /// 鉴权
        /// 
        /// 
        public async Task AuthenticateAsync()
        {
            string cookie = Context.Request.Cookies["AuthenticationScheme"];
            if (string.IsNullOrEmpty(cookie))
            {
                return AuthenticateResult.NoResult();
            }
            return await Task.FromResult(AuthenticateResult.Success(Deserialize(cookie)));
        }

        /// 
        /// 没有登录
        /// 
        /// 
        /// 
        public Task ChallengeAsync(AuthenticationProperties properties)
        {
            Context.Response.Redirect("/home/login");
            return Task.CompletedTask;
        }

        /// 
        /// 没有权限禁止访问
        /// 
        /// 
        /// 
        public Task ForbidAsync(AuthenticationProperties properties)
        {
            Context.Response.StatusCode = 403;
            return Task.CompletedTask;
        }

        /// 
        /// 初始化鉴权Handler
        /// 
        /// 鉴权组合
        /// http上下文
        /// 
        public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
        {
            Scheme = scheme;
            Context = context;
            return Task.CompletedTask;
        }

        /// 
        /// 登录
        /// 
        /// 
        /// 
        /// 
        public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
        {
            AuthenticationTicket ticket = new AuthenticationTicket(user, properties, Scheme.Name);
            Context.Response.Cookies.Append("AuthenticationScheme", Serialize(ticket));
            return Task.CompletedTask;
        }

        /// 
        /// 退出
        /// 
        /// 
        /// 
        public Task SignOutAsync(AuthenticationProperties properties)
        {
            Context.Response.Cookies.Delete("AuthenticationScheme");
            return Task.CompletedTask;
        }

        /// 
        /// 反序列化Ticket
        /// 
        /// 字符串Ticket
        /// 
        public AuthenticationTicket Deserialize(string ticket)
        {
            byte[] byteTicket = Encoding.Default.GetBytes(ticket);
            return TicketSerializer.Default.Deserialize(byteTicket);
        }

        /// 
        /// 序列化Ticket
        /// 
        /// AuthenticationTicket
        /// 
        public string Serialize(AuthenticationTicket ticket)
        {
            byte[] byteTicket = TicketSerializer.Default.Serialize(ticket);
            return Encoding.Default.GetString(byteTicket);
        }
    }
}

2.注册自定义Handler

    在Startup.cs的 ConfigureServices(IServiceCollection services)里注册
  //注册自定义Handler
  services.AddAuthenticationCore(options =>
    {
        options.AddScheme("AuthenticationScheme", "AuthenticationScheme");
    });

3.注册鉴权 授权 创建Ticket管道

    在Startup.cs的Configure(IApplicationBuilder app, IWebHostEnvironment env)里注册
    //拦截登录页面
    app.Map("/Home/Login", buider =>
    //创建Ticket中间件
    buider.UseAddAuthenticationCreate());
    //鉴权中间件
    app.UseAddAuthentication();
    //授权中间件
    app.UseAddAuthorizetion();
    //访问受保护资源
    app.Map("/resouce", builder => builder.Run(async (context) =>
        {
        await context.Response.WriteAsync($"welcome to .net core {context.User.Identity.Name}");
        }));
    app.Run(async (HttpContext context) =>
    {
        await context.Response.WriteAsync("Hello World,success!");
    });

4.中间件扩展方法

通过这个扩展方法可以把中间件B格提升一部分.
using System;
using CoreMvc.Utinity.MiddleWare.Authentications;
using Microsoft.AspNetCore.Builder;

namespace CoreMvc.Utinity.MiddleWare
{
    public static class MiddleWareExtension
    {
        /// 
        /// 创建Ticket中间件
        /// 
        /// IApplicationBuilder
        /// 
        public static IApplicationBuilder UseAddAuthenticationCreate(this IApplicationBuilder app)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            return app.UseMiddleware();
        }

        /// 
        /// 鉴权中间件
        /// 
        /// IApplicationBuilder
        /// 
        public static IApplicationBuilder UseAddAuthentication(this IApplicationBuilder app)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            return app.UseMiddleware();
        }

        /// 
        /// 授权中间件
        /// 
        /// IApplicationBuilder
        /// 
        public static IApplicationBuilder UseAddAuthorizetion(this IApplicationBuilder app)
        {

            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            return app.UseMiddleware();
        }
    }
}

5. 创建Ticket中间件

这里可以在登陆成功后赋予相应权限.
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;

namespace CoreMvc.Utinity.MiddleWare.Authentications
{
    /// 
    /// 创建鉴权Ticket
    /// 
    public class AuthenticationCreate
    {
        private readonly RequestDelegate _next;

        public AuthenticationCreate(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List
            {
                new Claim(ClaimTypes.Name, "fqydhk"),
                new Claim(ClaimTypes.MobilePhone, "13151********")
            }, "login");
            await context.SignInAsync("AuthenticationScheme", new ClaimsPrincipal(claimsIdentity));
            await _next(context);
        }
    }
}

6.鉴权中间件

通过这个中间件来实现查询是否有Ticket,如果有就放行
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;

namespace CoreMvc.Utinity.MiddleWare.Authentications
{
    /// 
    /// 鉴权
    /// 
    public class Authentication
    {
        private readonly RequestDelegate _next;
        public Authentication(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            AuthenticateResult result = await context.AuthenticateAsync("AuthenticationScheme");
            if (null != result?.Principal)
            {
                context.User = result.Principal;
                await _next(context);
            }
            else
            {
                await context.ChallengeAsync("AuthenticationScheme");
            }

        }
    }
}

7.授权中间件

通过这个中间件来实现具体的权限验证,验证通过就直接放行,一般用来判断角色是否有权使用具体业务
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;

namespace CoreMvc.Utinity.MiddleWare.Authentications
{
    /// 
    /// 授权
    /// 
    public class Authorization
    {
        private readonly RequestDelegate _next;
        public Authorization(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            System.Security.Claims.ClaimsPrincipal user = context.User;
            if (user.Identity.Name == "fqydhk")
            {
                await _next(context);
            }
            else
            {
                await context.ForbidAsync("AuthenticationScheme");
            }
        }
    }
}

以上就实现了简单的发放Ticket 鉴权 授权管理…有什么疑问欢迎留言,或者加QQ群大家一起探讨

你可能感兴趣的:(Asp.net,Core)