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;
        }
    }
}

 

posted @ 2017-06-12 10:30  `Laimic  阅读(424)  评论(0)    收藏  举报