详解ASP.NET MVC Form表单验证

2019-05-22 20:58:31于丽

写在配置文件里,是为了方便管理,如果程序里也写了,将覆盖配置文件的。ok,下面进入正题。

二、主要接口

先看两个主要用到的接口。

IPrincipal 定义了用户对象的基本功能,接口定义如下:

public interface IPrincipal
{
  //标识对象
  IIdentity Identity { get; }
  //判断当前角色是否属于指定的角色
  bool IsInRole(string role);
}

它有两个主要成员,IsInRole用于判断当前对象是否属于指定角色的,IIdentity定义了标识对象信息。HttpContext的User属性就是IPrincipal类型的。

IIdentity 定义了标识对象的基本功能,接口定义如下:

public interface IIdentity
{  
  //身份验证类型
  string AuthenticationType { get; }
  //是否验证通过
  bool IsAuthenticated { get; } 
  //用户名
  string Name { get; }
}

IIdentity包含了一些用户信息,但有时候我们需要存储更多信息,例如用户ID、用户角色等,这些信息会被序列到cookie中加密保存,验证通过时可以解码再反序列化获得,状态得以保存。例如定义一个UserData。

public class UserData : IUserData
{
  public long UserID { get; set; }
  public string UserName { get; set; }
  public string UserRole { get; set; }
 
  public bool IsInRole(string role)
  {
    if (string.IsNullOrEmpty(role))
    {
      return true;
    }
    return role.Split(',').Any(item => item.Equals(this.UserRole, StringComparison.OrdinalIgnoreCase));      
  }
 
  public bool IsInUser(string user)
  {
    if (string.IsNullOrEmpty(user))
    {
      return true;
    }
    return user.Split(',').Any(item => item.Equals(this.UserName, StringComparison.OrdinalIgnoreCase));
  }
}

  UserData实现了IUserData接口,该接口定义了两个方法:IsInRole和IsInUser,分别用于判断当前用户角色和用户名是否符合要求。该接口定义如下:

public interface IUserData
{
  bool IsInRole(string role);
  bool IsInUser(string user);
}
  接下来定义一个Principal实现IPrincipal接口,如下:
public class Principal : IPrincipal    
{
  public IIdentity Identity{get;private set;}
  public IUserData UserData{get;set;}
 
  public Principal(FormsAuthenticationTicket ticket, IUserData userData)
  {
    EnsureHelper.EnsureNotNull(ticket, "ticket");
    EnsureHelper.EnsureNotNull(userData, "userData");
    this.Identity = new FormsIdentity(ticket);
    this.UserData = userData;
  }
 
  public bool IsInRole(string role)
  {
    return this.UserData.IsInRole(role);      
  }   
 
  public bool IsInUser(string user)
  {
    return this.UserData.IsInUser(user);
  }
}

  Principal包含IUserData,而不是具体的UserData,这样很容易更换一个UserData而不影响其它代码。Principal的IsInRole和IsInUser间接调用了IUserData的同名方法。

三、写入cookie和读取cookie