Authentication身份认证方式分为两种:Windows、Forms;Windows认证方式适用于局域网。Forms认证方式既可适用于局域网,也可用于互联网。
在标准ASP.NET认证方式中
1. 如何判断当前请求是一个已登录用户发起的?
如果Request.IsAuthenticated为true,则表示是一个已登录用户。
2. 如何获取当前登录用户的登录名?如何获取当前用户的其他信息?
如果是一个已登录用户,访问HttpContext.User.Identity.Name可获取登录名(都是实例属性)。
ASP.NET身份认证过程
在ASP.NET中,整个身份认证的过程其实可分为二个阶段:认证与授权。
1. 认证阶段:识别当前请求的用户是不是一个可识别(的已登录)用户。
2. 授权阶段:是否允许当前请求访问指定的资源。
这二个阶段在ASP.NET管线中用AuthenticateRequest和AuthorizeRequest事件来表示。
在认证阶段,ASP.NET会检查当前请求,根据web.config设置的认证方式,尝试构造HttpContext.User对象供我们在后续的处理中使用。 在授权阶段,会检查当前请求所访问的资源是否允许访问,因为有些受保护的页面资源可能要求特定的用户或者用户组才能访问。 所以,即使是一个已登录用户,也有可能会不能访问某些页面。 当发现用户不能访问某个页面资源时,ASP.NET会将请求重定向到登录页面。
受保护的页面与登录页面我们都可以在web.config中指定,具体方法可参考后文。
在ASP.NET中,Forms认证是由FormsAuthenticationModule实现的,URL的授权检查是由UrlAuthorizationModule实现的。
Authentication身份认证
1. web.config中配置认证方式
<authentication mode="Forms" > <forms name="cookieName" loginUrl="~/Account/Login" timeout="2880" ></forms> </authentication>
2. 在登录时,将登录信息写入cookie
string userData = JsonConvert.SerializeObject(model);//model为用户的基本信息(如角色、权限等)写入cookie,可用于授权检查 //写入注册信息 DateTime expiration = DateTime.Now.Add(FormsAuthentication.Timeout); FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, model.Email, DateTime.Now, expiration, true, userData, FormsAuthentication.FormsCookiePath ); HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)) { HttpOnly = true, Expires = expiration }; HttpContext.Response.Cookies.Remove(cookie.Name); HttpContext.Response.Cookies.Add(cookie);
3. 身份认证过滤器,并在global中进行配置
public class AuthenticationFilter : ActionFilterAttribute { /// <summary> /// 身份认证过滤,用户权限判断 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuting(ActionExecutingContext filterContext) { bool isAnoy = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true); var identity = filterContext.HttpContext.User.Identity; if (!isAnoy && !identity.IsAuthenticated) { if (filterContext.HttpContext.Request.IsAjaxRequest()) { var result = new { flag = false, data = string.Empty, msg = "请登录" }; filterContext.Result = new JsonResult { Data = result, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } else { filterContext.Result = new RedirectToRouteResult(new System.Web.Routing.RouteValueDictionary(new { //需要跳转的Controller controller = "Account", //需要跳转的Action action = "Login", //返回的字段说明 returnUrl = filterContext.HttpContext.Request.Url, returnMessage = "请登录!" })); } } } }
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); filters.Add(new AuthenticationFilter()); } }
4. 自定义的IPrincipa和IIdentity实现用户角色验证,获取更详细的用户信息或是更详细的权限验证
public class CustomPrincipal : IPrincipal { #region Identity Properties public int UserId { get; set; } public string LoginName { get; set; } public string RealName { get; set; } public string Email { get; set; } public string[] Roles { get; set; } #endregion public IIdentity Identity { get; private set; } public bool IsInRole(string role) { if (Roles.Any(r => role.Contains(r))) { return true; } else { return false; } } public CustomPrincipal(string username) { Identity = new GenericIdentity(username); } }
在global中实现Application_PostAuthenticateRequest
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e) { //读取cookie并替换HttpContext.User对象 HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];// Request.Cookies["cookieName"]; if (authCookie != null) { FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); CustomPrincipal principal = new CustomPrincipal(authTicket.Name); //可将需要在整个程序读取的用户数据放在principal中 //var userDto = JsonConvert.DeserializeObject<UserDto>(authTicket.UserData); //principal.UserId = userDto.Id; //principal.LoginName = userDto.LoginName; //principal.RealName = userDto.RealName; //principal.Roles = serializeModel.RoleName.ToArray<string>(); HttpContext.Current.User = principal; } }
这些是最近用到的,有更多认识,再来补充