Asp.Net Core 6 Cookie 的身份验证策略

参考文献:

http://www.js-code.com/xindejiqiao/xindejiqiao_274882.html

https://www.cnblogs.com/xiaoxiaotank/p/15811749.html

编写代码过程中不理解的代码可参考上面的文献

首先需要配置你的Program.cs,代码如下:

 //在ASP.NET Core应用程序中配置依赖注入容器,将 HttpContextAccessor 注册为一个服务
        builder.Services.AddHttpContextAccessor();

        //选择使用那种方式来身份验证(Cookie)
        builder.Services.AddAuthentication(option =>
        {
            option.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; //默认身份验证方案Cookie
            option.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            option.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            option.DefaultForbidScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            option.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        }).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, option =>
        {
            option.LoginPath = "/Login/AdminLoginView";//如果没有找到用户信息---身份验证失败--授权也失败了---就跳转到指定的Action
            option.AccessDeniedPath = "/Login/AdminLoginView";//访问被拒绝就跳转到指定的Action
        });

然后开启中间件

// 身份认证中间件
app.UseAuthentication();

app.UseAuthorization();

 创建一个AuthenticationMiddleware.cs类

private readonly RequestDelegate _next;

        public AuthenticationMiddleware(RequestDelegate next, IAuthenticationSchemeProvider schemes)
        {
            _next = next;
            Schemes = schemes;
        }

        public IAuthenticationSchemeProvider Schemes { get; set; }

        public async Task Invoke(HttpContext context)
        {
            // 记录原始路径和原始基路径
            context.Features.Set<IAuthenticationFeature>(new AuthenticationFeature
            {
                OriginalPath = context.Request.Path,
                OriginalPathBase = context.Request.PathBase
            });

            // 如果有显式指定的身份认证方案,优先处理(这里不用看,直接看下面)
            var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
            foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
            {
                var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler;
                if (handler != null && await handler.HandleRequestAsync())
                {
                    return;
                }
            }

            // 使用默认的身份认证方案进行认证,并赋值 HttpContext.User
            var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
            if (defaultAuthenticate != null)
            {
                var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
                if (result?.Principal != null)
                {
                    context.User = result.Principal;
                }
            }

            await _next(context);
        }

在写登录的地方去使用

/// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ResultDto<int>> AdminLogin(LoginDto dto)
        {
            try
            {
                var model = await _adminRepository.FindAsync(a => a.AdminAccount == dto.LoginName);
                if (model.AdminAccount == null)
                {
                    return new ResultDto<int>
                    {
                        code = 0,
                        data = 2,
                        msg = "用户不存在",
                    };
                }

                bool isCode = Validate2(dto.Id, dto.ValidateCode);
                if (!isCode)
                {
                    return new ResultDto<int>
                    {
                        code = 0,
                        data = 3,
                        msg = "验证码错误"
                    };
                }

                if (model.AdminPassword.ToUpper() == dto.LoginPassword.Md5().ToUpper())
                {
                    var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
                    identity.AddClaims(new[]
                    {
                        new Claim(ClaimTypes.NameIdentifier,model.AdminId.ToString()),//存储登录的角色的AdminId
                        new Claim(ClaimTypes.Name,model.AdminName),//存储登录的角色的AdminName
                    });
                    var principal = new ClaimsPrincipal(identity);

                    // 登录设置项 比如过期时间
                    var properties = new AuthenticationProperties
                    {
                        ExpiresUtc = DateTimeOffset.UtcNow.AddSeconds(60),
                        AllowRefresh = true
                    };

                    await _httpcontext.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, properties);

                    return new ResultDto<int>
                    {
                        code = 0,
                        data = 1,
                        msg = "登陆成功"
                    };
                }
                else
                {
                    return new ResultDto<int>
                    {
                        code = 0,
                        data = 4,
                        msg = "密码错误"
                    };
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

 最后给你的控制器加上[Authorize]特性就可以了。

posted on 2023-07-26 17:13  格子衬衫身上穿  阅读(222)  评论(0编辑  收藏  举报

导航