ASP .NET MVC - Authorize
使用 MVC 自带的Authorize 来进行身份验证登录
首选需要在 Web.config 中的 <system.web> 节点中配置, 身份验证失败所要导向的页面
名字随便起
<authentication mode="Forms"> <forms name="LITAUTH" loginUrl="/Admin/Login/Login"></forms> </authentication>
之后, 如果是需要全局验证的话, 则需要在 FilterConfig.RegisterglobalFilters 中添加代码
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new AuthorizeAttribute()); }
再在Global中注册
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); }
这样的话, 所有的控制器都需要登录才能操作了
其中包含了登录用的控制器, 这不是矛盾吗
没事, 我们可以在需要匿名访问的控制器上面加上
[AllowAnonymous]
这样可以匿名访问登录用的控制器了
接下来应该就是在登录的时候创建身份验证了
将身份保存到 Cookie中
public class CurrentUserCookie : IPrincipal { /// <summary> /// 当前用户 /// </summary> public UserInfo CurrentUser { get; set; } #region IPincipal 成员 /// <summary> /// 身份 /// </summary> [Newtonsoft.Json.JsonIgnore] public IIdentity Identity { get; private set; } /// <summary> /// 该用户是否是该对象 /// </summary> /// <param name="role"></param> /// <returns></returns> bool IPrincipal.IsInRole(string role) => true; public void GenericIdentity(string username) => Identity = new GenericIdentity(username); #endregion }
/// <summary> /// 用户的信息 /// 这个是直接在 Controller 中用的 /// </summary> public class UserInfo { /// <summary> /// 用户工号 /// </summary> public string UserId { get; set; } /// <summary> /// 员工姓名 /// </summary> public string Name { get; set; } /// <summary> /// 部门 /// </summary> public string Department { get; set; } /// <summary> /// 岗位 /// </summary> public string Post { get; set; } }
登录的时候用以下方法
// 自定义的一个类 // 用于记录用户登录信息 CurrentUserCookie serializeModel = new CurrentUserCookie { CurrentUser = new UserInfo { UserId = _account.Id, Username = _account.Username, Name = _account.Name } }; // 将整个用户登录信息记录到 Http 上下文中 // 应该可以视其为一个全局变量 System.Web.HttpContext.Current.User = serializeModel; // Json 格式化用户登录信息 string userData = Newtonsoft.Json.JsonConvert.SerializeObject(serializeModel); // 打算将用户登录信息保存到 Cookie 中 // 如果不执行这段, 我也不知道会发生什么 // 先建立一个票证 // 设置下失效时间 // 可能类似于去看博物馆, 手上的票有时间限制 FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket( 1, _account.Id.ToString(), DateTime.Now, DateTime.Now.AddYears(5), true, userData); // 加密票证 string encTicket = FormsAuthentication.Encrypt(authTicket); // 创建 Cookie 对象 // FormsCookieName 就是 web.config 设置的名字 // 应该是用于 cookie 记录的 key // encTicket 就是加密后的票据 HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket); cookie.HttpOnly = true; // 设置过期时间, 自己定义 cookie.Expires = DateTime.Now.AddMonths(1); // 添加到 Cookie 中 System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
在 Global.cs 中进行实体替换
目的是从 Cookie 中提取 CurrentUserCookie 信息然后放到 HttpContext 上下文的 Current.User 中
因为 Cookie 中是加密过的信息 没办法直接拿来用, 只能通过实体替换获得用户的实体
protected void Application_PostAuthenticateRequest(object sender, EventArgs e) { HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; if(authCookie != null) { try { FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); CurrentUserCookie user = Newtonsoft.Json.JsonConvert.DeserializeObject<CurrentUserCookie>(authTicket.UserData); user.GenericIdentity(authTicket.Name); // 实体替换 HttpContext.Current.User = user; } catch { return; } } }
接着在 BaseController 中设立 UserInfo
为了方便自己可以在 Controller 中获得用户的各种信息
public class BaseController : Controller { public static UserInfo CurrentUser { get { // 取上下文中的用户信息 return (System.Web.HttpContext.Current.User as CurrentUserCookie).CurrentUser; } } }