asp.net core 2.0 Cookie验证用户登录

  添加UserAuthorizeAttribute:

  

   /// <summary>
    /// 跳过属性检查
    /// </summary>
    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple =false,Inherited =true)]
    public sealed class SkipUserAuthorizeAttribute:Attribute,IFilterMetadata
    {

    }
    /// <summary>
    /// 用户登录验证
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class UserAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
    {
        public const string UserAuthenticationScheme = "UserAuthenticationScheme";//自定义一个默认的登录方案
        public UserAuthorizeAttribute()
        {
            this.AuthenticationSchemes = UserAuthenticationScheme;
        }
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            //获取登录方案
            var authenticate = context.HttpContext.AuthenticateAsync(UserAuthorizeAttribute.UserAuthenticationScheme);
            if (authenticate.Result.Succeeded || this.SkipUserAuthorize(context.ActionDescriptor))
            {
                return;
            }

            HttpRequest httpRequest = context.HttpContext.Request;
            if(httpRequest.IsAjaxRequest())//ajax请求
            {
                AjaxResult result = new AjaxResult();
                result.Status = "redirect";//需要重定向
                result.ErrorMsg = "登录超时";
                result.Data = "";
                context.Result = new JsonResult(result);
            }
            else
            {
                RedirectResult redirectResult = new RedirectResult("~/Account/Login");
                context.Result = redirectResult;
            }
            
            return;
        }
        protected virtual bool SkipUserAuthorize(ActionDescriptor actionDescriptor)
        {
            return actionDescriptor.FilterDescriptors
                .Where(a => a.Filter is SkipUserAuthorizeAttribute).Any();
        }
    }

  由于在ajax请求中需要做特殊判断,这里自定义的IsAjaxRequst方法:

  

   public static bool IsAjaxRequest(this HttpRequest request)
        {
            bool result = false;
            var xreq = request.Headers.ContainsKey("x-requested-with");
            if (xreq)
            {
                result = request.Headers["x-requested-with"] == "XMLHttpRequest";
            }

            return result;
        }

  startup中注册cookie:

  

       #region 注册cookie
            //注册cookie认证服务
            services.AddAuthentication(UserAuthorizeAttribute.UserAuthenticationScheme)
                .AddCookie(UserAuthorizeAttribute.UserAuthenticationScheme,options => {
                    options.LoginPath = "/Account/Login";
                    options.LogoutPath = "/Account/Logout";
                });
            #endregion

  action中检查登录:

      [UserAuthorize]
        public IActionResult Index()
        {
            return View();
        }

  登陆后cookie的保存:

        
//登录验证成功后,admin=当前用户
//Cookies //创建身份认证Cookie var claimIdentity = new ClaimsIdentity(UserAuthorizeAttribute.UserAuthenticationScheme); claimIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, admin.Id.ToString())); claimIdentity.AddClaim(new Claim(ClaimTypes.Name, admin.Name)); claimIdentity.AddClaim(new Claim("Account", model.Account)); claimIdentity.AddClaim(new Claim("Password", model.Password)); if (model.RememberMe == "on") { claimIdentity.AddClaim(new Claim("RememberMe", "on")); } else { claimIdentity.AddClaim(new Claim("RememberMe", "off")); } var claimsPrincipal = new ClaimsPrincipal(claimIdentity); HttpContext.SignInAsync(claimsPrincipal, new AuthenticationProperties { ExpiresUtc = DateTime.Now.AddDays(7),//有效时间1周 IsPersistent=true, AllowRefresh=false, });

  需要取cookie的时候:

            //获取cookie中用户信息
            var adminAccount =HttpContext.User.Claims.SingleOrDefault(t=>t.Type=="Account");
            string account = adminAccount == null ? "" : adminAccount.Value;
            var adminPwd = HttpContext.User.Claims.SingleOrDefault(t => t.Type == "Password");
            string pwd = adminPwd == null ? "" : adminPwd.Value;
            var rememberMe = HttpContext.User.Claims.SingleOrDefault(t => t.Type == "RememberMe");
            string rem = rememberMe == null ? "" : rememberMe.Value;

  在view中,特别是layout中,比如要显示用户名,当然需要引入对应的命名空间:

  

             <span>@User.Claims.SingleOrDefault(t=>t.Type== ClaimTypes.Name).Value</span>

  至此,基本完成,可能还有缺陷,望您指正,感谢。

  全部解析过程,参考大神的分享:

  《Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录》