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>
至此,基本完成,可能还有缺陷,望您指正,感谢。
全部解析过程,参考大神的分享: