婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 詳解ASP.NET MVC Form表單驗證

詳解ASP.NET MVC Form表單驗證

熱門標(biāo)簽:遂寧市地圖標(biāo)注app 地圖標(biāo)注專業(yè)團隊 濮陽外呼電銷系統(tǒng)怎么樣 塔城代理外呼系統(tǒng) 地圖標(biāo)注的公司有哪些 地圖定位圖標(biāo)標(biāo)注 天心智能電銷機器人 400電話辦理哪家性價比高 代理接電話機器人如何取消

一、前言

  關(guān)于表單驗證,已經(jīng)有不少的文章,相信Web開發(fā)人員也都基本寫過,最近在一個個人項目中剛好用到,在這里與大家分享一下。本來想從用戶注冊開始寫起,但發(fā)現(xiàn)東西比較多,涉及到界面、前端驗證、前端加密、后臺解密、用戶密碼Hash、權(quán)限驗證等等,文章寫起來可能會很長,所以這里主要介紹的是登錄驗證和權(quán)限控制部分,有興趣的朋友歡迎一起交流。

  一般驗證方式有Windows驗證和表單驗證,web項目用得更多的是表單驗證。原理很簡單,簡單地說就是利用瀏覽器的cookie,將驗證令牌存儲在客戶端瀏覽器上,cookie每次會隨請求發(fā)送到服務(wù)器,服務(wù)器驗證這個令牌。通常一個系統(tǒng)的用戶會分為多種角色:匿名用戶、普通用戶和管理員;這里面又可以再細(xì)分,例如用戶可以是普通用戶或Vip用戶,管理員可以是普通管理員或超級管理員等。在項目中,我們有的頁面可能只允許管理員查看,有的只允許登錄用戶查看,這就是角色區(qū)分(Roles);某些特別情況下,有些頁面可能只允許叫“張三”名字的人查看,這就是用戶區(qū)分(Users)。

  我們先看一下最后要實現(xiàn)的效果:

1.這是在Action級別的控制。

public class Home1Controller : Controller
{
  //匿名訪問
  public ActionResult Index()
  {
    return View();
  }
  //登錄用戶訪問
  [RequestAuthorize]
  public ActionResult Index2()
  {
    return View();
  }
  //登錄用戶,張三才能訪問
  [RequestAuthorize(Users="張三")]
  public ActionResult Index3()
  {
    return View();
  }
  //管理員訪問
  [RequestAuthorize(Roles="Admin")]
  public ActionResult Index4()
  {
    return View();
  }
}

2.這是在Controller級別的控制。當(dāng)然,如果某個Action需要匿名訪問,也是允許的,因為控制級別上,Action優(yōu)先級大于Controller。

//Controller級別的權(quán)限控制
[RequestAuthorize(User="張三")]
public class Home2Controller : Controller
{
  //登錄用戶訪問
  public ActionResult Index()
  {
    return View();
  }
  //允許匿名訪問
  [AllowAnonymous]
  public ActionResult Index2()
  {
    return View();
  }
}

3.Area級別的控制。有時候我們會把一些模塊做成分區(qū),當(dāng)然這里也可以在Area的Controller和Action進(jìn)行標(biāo)記。

  從上面可以看到,我們需要在各個地方進(jìn)行標(biāo)記權(quán)限,如果把Roles和Users硬寫在程序中,不是很好的做法。我希望能更簡單一點,在配置文件進(jìn)行說明。例如如下配置:

?xml version="1.0" encoding="utf-8" ?>
!--
  1.這里可以把權(quán)限控制轉(zhuǎn)移到配置文件,這樣就不用在程序中寫roles和users了
  2.如果程序也寫了,那么將覆蓋配置文件的。
  3.action級別的優(yōu)先級 > controller級別 > Area級別  
-->
root>
 !--area級別-->
 area name="Admin">
  roles>Admin/roles>
 /area>
  
 !--controller級別-->
 controller name="Home2">
  user>張三/user>
 /controller>
  
 !--action級別-->
 controller name="Home1">
  action name="Inde3">
   users>張三/users>
  /action>
  action name="Index4">
   roles>Admin/roles>
  /action>
 /controller>
/root>

寫在配置文件里,是為了方便管理,如果程序里也寫了,將覆蓋配置文件的。ok,下面進(jìn)入正題。

二、主要接口

先看兩個主要用到的接口。

IPrincipal 定義了用戶對象的基本功能,接口定義如下:

public interface IPrincipal
{
  //標(biāo)識對象
  IIdentity Identity { get; }
  //判斷當(dāng)前角色是否屬于指定的角色
  bool IsInRole(string role);
}

它有兩個主要成員,IsInRole用于判斷當(dāng)前對象是否屬于指定角色的,IIdentity定義了標(biāo)識對象信息。HttpContext的User屬性就是IPrincipal類型的。

IIdentity 定義了標(biāo)識對象的基本功能,接口定義如下:

public interface IIdentity
{  
  //身份驗證類型
  string AuthenticationType { get; }
  //是否驗證通過
  bool IsAuthenticated { get; } 
  //用戶名
  string Name { get; }
}

IIdentity包含了一些用戶信息,但有時候我們需要存儲更多信息,例如用戶ID、用戶角色等,這些信息會被序列到cookie中加密保存,驗證通過時可以解碼再反序列化獲得,狀態(tài)得以保存。例如定義一個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實現(xiàn)了IUserData接口,該接口定義了兩個方法:IsInRole和IsInUser,分別用于判斷當(dāng)前用戶角色和用戶名是否符合要求。該接口定義如下:

public interface IUserData
{
  bool IsInRole(string role);
  bool IsInUser(string user);
}
  接下來定義一個Principal實現(xiàn)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間接調(diào)用了IUserData的同名方法。

三、寫入cookie和讀取cookie

  接下來,需要做的就是用戶登錄成功后,創(chuàng)建UserData,序列化,再利用FormsAuthentication加密,寫到cookie中;而請求到來時,需要嘗試將cookie解密并反序列化。如下:

public class HttpFormsAuthentication
{    
  public static void SetAuthenticationCookie(string userName, IUserData userData, double rememberDays = 0)            
  {
    EnsureHelper.EnsureNotNullOrEmpty(userName, "userName");
    EnsureHelper.EnsureNotNull(userData, "userData");
    EnsureHelper.EnsureRange(rememberDays, "rememberDays", 0);
 
    //保存在cookie中的信息
    string userJson = JsonConvert.SerializeObject(userData);
 
    //創(chuàng)建用戶票據(jù)
    double tickekDays = rememberDays == 0 ? 7 : rememberDays;
    var ticket = new FormsAuthenticationTicket(2, userName,
      DateTime.Now, DateTime.Now.AddDays(tickekDays), false, userJson);
 
    //FormsAuthentication提供web forms身份驗證服務(wù)
    //加密
    string encryptValue = FormsAuthentication.Encrypt(ticket);
 
    //創(chuàng)建cookie
    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptValue);
    cookie.HttpOnly = true;
    cookie.Domain = FormsAuthentication.CookieDomain;
 
    if (rememberDays > 0)
    {
      cookie.Expires = DateTime.Now.AddDays(rememberDays);
    }      
    HttpContext.Current.Response.Cookies.Remove(cookie.Name);
    HttpContext.Current.Response.Cookies.Add(cookie);
  }
 
  public static Principal TryParsePrincipalTUserData>(HttpContext context)              
    where TUserData : IUserData
  {
    EnsureHelper.EnsureNotNull(context, "context");
 
    HttpRequest request = context.Request;
    HttpCookie cookie = request.Cookies[FormsAuthentication.FormsCookieName];
    if(cookie == null || string.IsNullOrEmpty(cookie.Value))
    {
      return null;
    }
    //解密cookie值
    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
    if(ticket == null || string.IsNullOrEmpty(ticket.UserData))          
    {
      return null;            
    }
    IUserData userData = JsonConvert.DeserializeObjectTUserData>(ticket.UserData);       
    return new Principal(ticket, userData);
  }
}

  在登錄時,我們可以類似這樣處理:

public ActionResult Login(string userName,string password)
{
  //驗證用戶名和密碼等一些邏輯... 
 
  UserData userData = new UserData()
  {
    UserName = userName,
    UserID = userID,
    UserRole = "Admin"
  };
  HttpFormsAuthentication.SetAuthenticationCookie(userName, userData, 7);
   
  //驗證通過...
}

  登錄成功后,就會把信息寫入cookie,可以通過瀏覽器觀察請求,就會有一個名稱為"Form"的Cookie(還需要簡單配置一下配置文件),它的值是一個加密后的字符串,后續(xù)的請求根據(jù)此cookie請求進(jìn)行驗證。具體做法是在HttpApplication的AuthenticateRequest驗證事件中調(diào)用上面的TryParsePrincipal,如:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
  HttpContext.Current.User = HttpFormsAuthentication.TryParsePrincipalUserData>(HttpContext.Current);
}

  這里如果驗證不通過,HttpContext.Current.User就是null,表示當(dāng)前用戶未標(biāo)識。但在這里還不能做任何關(guān)于權(quán)限的處理,因為上面說到的,有些頁面是允許匿名訪問的。

三、AuthorizeAttribute

  這是一個Filter,在Action執(zhí)行前執(zhí)行,它實現(xiàn)了IActionFilter接口。關(guān)于Filter,可以看我之前的這篇文章,這里就不多介紹了。我們定義一個RequestAuthorizeAttribute繼承AuthorizeAttribute,并重寫它的OnAuthorization方法,如果一個Controller或者Action標(biāo)記了該特性,那么該方法就會在Action執(zhí)行前被執(zhí)行,在這里判斷是否已經(jīng)登錄和是否有權(quán)限,如果沒有則做出相應(yīng)處理。具體代碼如下:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class RequestAuthorizeAttribute : AuthorizeAttribute
{
  //驗證
  public override void OnAuthorization(AuthorizationContext context)
  {
    EnsureHelper.EnsureNotNull(context, "httpContent");      
    //是否允許匿名訪問
    if (context.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), false))
    {
      return;
    }
    //登錄驗證
    Principal principal = context.HttpContext.User as Principal;
    if (principal == null)
    {
      SetUnAuthorizedResult(context);
      HandleUnauthorizedRequest(context);
      return;
    }
    //權(quán)限驗證
    if (!principal.IsInRole(base.Roles) || !principal.IsInUser(base.Users))
    {
      SetUnAuthorizedResult(context);
      HandleUnauthorizedRequest(context);
      return;
    }
    //驗證配置文件
    if(!ValidateAuthorizeConfig(principal, context))
    {
      SetUnAuthorizedResult(context);
      HandleUnauthorizedRequest(context);
      return;
    }      
  }
 
  //驗證不通過時
  private void SetUnAuthorizedResult(AuthorizationContext context)
  {
    HttpRequestBase request = context.HttpContext.Request;
    if (request.IsAjaxRequest())
    {
      //處理ajax請求
      string result = JsonConvert.SerializeObject(JsonModel.Error(403));        
      context.Result = new ContentResult() { Content = result };
    }
    else
    {
      //跳轉(zhuǎn)到登錄頁面
      string loginUrl = FormsAuthentication.LoginUrl + "?ReturnUrl=" + preUrl;
      context.Result = new RedirectResult(loginUrl);
    }
  }
 
  //override
  protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
  {
    if(filterContext.Result != null)
    {
      return;
    }
    base.HandleUnauthorizedRequest(filterContext);
  }
}

  注:這里的代碼摘自個人項目中的,簡寫了部分代碼,有些是輔助類,代碼沒有貼出,但應(yīng)該不影響閱讀。

  1. 如果我們在HttpApplication的AuthenticateRequest事件中獲得的IPrincipal為null,那么驗證不通過。

  2. 如果驗證通過,程序會進(jìn)行驗證AuthorizeAttribute的Roles和User屬性。

  3. 如果驗證通過,程序會驗證配置文件中對應(yīng)的Roles和Users屬性。

  驗證配置文件的方法如下:

  private bool ValidateAuthorizeConfig(Principal principal, AuthorizationContext context)
  {
    //action可能有重載,重載時應(yīng)該標(biāo)記ActionName區(qū)分
    ActionNameAttribute actionNameAttr = context.ActionDescriptor
      .GetCustomAttributes(typeof(ActionNameAttribute), false)
      .OfTypeActionNameAttribute>().FirstOrDefault();
    string actionName = actionNameAttr == null ? null : actionNameAttr.Name;
    AuthorizationConfig ac = ParseAuthorizeConfig(actionName, context.RouteData);
    if (ac != null)
    {
      if (!principal.IsInRole(ac.Roles))
      {
        return false;
      }
      if (!principal.IsInUser(ac.Users))
      {
        return false;
      }
    }
    return true;
  }
 
  private AuthorizationConfig ParseAuthorizeConfig(string actionName, RouteData routeData)
  {
    string areaName = routeData.DataTokens["area"] as string;
    string controllerName = null;
    object controller, action;
    if(string.IsNullOrEmpty(actionName))
    {
      if(routeData.Values.TryGetValue("action", out action))
      {
        actionName = action.ToString();
      }
    }
    if (routeData.Values.TryGetValue("controller", out controller))
    {
      controllerName = controller.ToString();
    }
    if(!string.IsNullOrEmpty(controllerName)  !string.IsNullOrEmpty(actionName))
    {
      return AuthorizationConfig.ParseAuthorizationConfig(
        areaName, controllerName, actionName);
    }
    return null;
  }
}

  可以看到,它會根據(jù)當(dāng)前請求的area、controller和action名稱,通過一個AuthorizationConfig類進(jìn)行驗證,該類的定義如下:

public class AuthorizationConfig
{
  public string Roles { get; set; }
  public string Users { get; set; }
 
  private static XDocument _doc;
 
  //配置文件路徑
  private static string _path = "~/Identity/Authorization.xml";
 
  //首次使用加載配置文件
  static AuthorizationConfig()
  {
    string absPath = HttpContext.Current.Server.MapPath(_path);
    if (File.Exists(absPath))
    {
      _doc = XDocument.Load(absPath);
    }
  }
 
  //解析配置文件,獲得包含Roles和Users的信息
  public static AuthorizationConfig ParseAuthorizationConfig(string areaName, string controllerName, string actionName)
  {
    EnsureHelper.EnsureNotNullOrEmpty(controllerName, "controllerName");
    EnsureHelper.EnsureNotNullOrEmpty(actionName, "actionName");
 
    if (_doc == null)
    {
      return null;
    }
    XElement rootElement = _doc.Element("root");
    if (rootElement == null)
    {
      return null;
    }
    AuthorizationConfig info = new AuthorizationConfig();
    XElement rolesElement = null;
    XElement usersElement = null;
    XElement areaElement = rootElement.Elements("area")
      .Where(e => CompareName(e, areaName)).FirstOrDefault();
    XElement targetElement = areaElement ?? rootElement;
    XElement controllerElement = targetElement.Elements("controller")
      .Where(e => CompareName(e, controllerName)).FirstOrDefault();
 
    //如果沒有area節(jié)點和controller節(jié)點則返回null
    if (areaElement == null  controllerElement == null)
    {
      return null;
    }
    //此時獲取標(biāo)記的area
    if (controllerElement == null)
    {
      rootElement = areaElement.Element("roles");
      usersElement = areaElement.Element("users");
    }
    else
    {
      XElement actionElement = controllerElement.Elements("action")
        .Where(e => CompareName(e, actionName)).FirstOrDefault();
      if (actionElement != null)
      {
        //此時獲取標(biāo)記action的
        rolesElement = actionElement.Element("roles");
        usersElement = actionElement.Element("users");
      }
      else
      {
        //此時獲取標(biāo)記controller的
        rolesElement = controllerElement.Element("roles");
        usersElement = controllerElement.Element("users");
      }
    }
    info.Roles = rolesElement == null ? null : rolesElement.Value;
    info.Users = usersElement == null ? null : usersElement.Value;
    return info;
  }
 
  private static bool CompareName(XElement e, string value)
  {
    XAttribute attribute = e.Attribute("name");
    if (attribute == null || string.IsNullOrEmpty(attribute.Value))
    {
      return false;
    }
    return attribute.Value.Equals(value, StringComparison.OrdinalIgnoreCase);
  }
}

這里的代碼比較長,但主要邏輯就是解析文章開頭的配置信息。

簡單總結(jié)一下程序?qū)崿F(xiàn)的步驟:

  1. 校對用戶名和密碼正確后,調(diào)用SetAuthenticationCookie將一些狀態(tài)信息寫入cookie。

  2. 在HttpApplication的Authentication事件中,調(diào)用TryParsePrincipal獲得狀態(tài)信息。

  3. 在需要驗證的Action(或Controller)標(biāo)記 RequestAuthorizeAttribute特性,并設(shè)置Roles和Users;Roles和Users也可以在配置文件中配置。

  4. 在RequestAuthorizeAttribute的OnAuthorization方法中進(jìn)行驗證和權(quán)限邏輯處理。

四、總結(jié)

  上面就是整個登錄認(rèn)證的核心實現(xiàn)過程,只需要簡單配置一下就可以實現(xiàn)了。但實際項目中從用戶注冊到用戶管理整個過程是比較復(fù)雜的,而且涉及到前后端驗證、加解密問題。關(guān)于安全問題,F(xiàn)ormsAuthentication在加密的時候,會根據(jù)服務(wù)器的MachineKey等一些信息進(jìn)行加密,所以相對安全。當(dāng)然,如果說請求被惡意攔截,然后被偽造登錄還是有可能的,這是后面要考慮的問題了,例如使用安全的http協(xié)議https。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。

您可能感興趣的文章:
  • 淺談asp.net Forms身份驗證詳解
  • 關(guān)于C#.net winform程序驗證moss的集成身份認(rèn)證實例
  • Asp.Net二級域名共享Forms身份驗證、下載站/圖片站的授權(quán)訪問控制
  • ASP.NET Internet安全Forms身份驗證方法
  • asp.net forms身份驗證,避免重復(fù)造輪子
  • asp.net 基于forms驗證的目錄角色權(quán)限的實現(xiàn)
  • asp.net Forms身份驗證和基于角色的權(quán)限訪問
  • asp.net 特定目錄form驗證
  • ASP.net Forms驗證Demo
  • .net MVC使用IPrincipal進(jìn)行Form登錄即權(quán)限驗證(3)

標(biāo)簽:河南 重慶 吉林 婁底 汕頭 麗江 宜春 本溪

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解ASP.NET MVC Form表單驗證》,本文關(guān)鍵詞  詳解,ASP.NET,MVC,Form,表單,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《詳解ASP.NET MVC Form表單驗證》相關(guān)的同類信息!
  • 本頁收集關(guān)于詳解ASP.NET MVC Form表單驗證的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    亚洲精品在线免费观看视频| 亚洲国产中文字幕在线视频综合| 亚洲精品亚洲人成人网在线播放| 亚洲国产日日夜夜| 国产精品99久久久久久似苏梦涵 | 国产亚洲精品aa| 午夜精品成人在线视频| 成人毛片老司机大片| 欧美女孩性生活视频| 中文字幕亚洲成人| 国产精品一区二区男女羞羞无遮挡| 欧美三级视频在线观看| 国产精品国模大尺度视频| 美女视频黄久久| 在线综合亚洲欧美在线视频| 亚洲欧洲制服丝袜| 国产高清成人在线| 久久只精品国产| 青青青爽久久午夜综合久久午夜| 色综合久久久久久久| 国产精品福利一区二区| 成人黄色国产精品网站大全在线免费观看| 91精品免费观看| 午夜视频一区二区三区| 欧美在线一二三| 一区二区三区欧美亚洲| 99精品欧美一区二区三区综合在线| 国产三区在线成人av| 国产精品夜夜爽| 久久精品免视看| 国产经典欧美精品| 国产午夜精品理论片a级大结局| 极品少妇一区二区三区精品视频| 在线播放亚洲一区| 日韩在线播放一区二区| 日韩一区二区影院| 免费在线欧美视频| 欧美大片在线观看| 国产成人一级电影| 国产精品每日更新在线播放网址| 不卡免费追剧大全电视剧网站| 国产情人综合久久777777| 成人黄色av电影| 亚洲日本中文字幕区| 91伊人久久大香线蕉| 亚洲另类春色校园小说| 在线免费视频一区二区| 午夜精品免费在线| 精品国产伦一区二区三区观看方式 | 高清不卡一二三区| 自拍偷在线精品自拍偷无码专区 | 国产裸体歌舞团一区二区| 久久亚洲影视婷婷| 不卡一区二区中文字幕| 亚洲夂夂婷婷色拍ww47| 91精品黄色片免费大全| 狠狠色丁香九九婷婷综合五月| 国产精品天美传媒沈樵| 欧洲国内综合视频| 麻豆一区二区三| 国产精品免费看片| 欧美日韩电影在线| 国产一区二区三区在线观看免费| 国产精品福利av| 91精品国产综合久久香蕉麻豆| 国产美女娇喘av呻吟久久| 亚洲色图第一区| 欧美一级片在线| 成人午夜在线播放| 秋霞影院一区二区| 中文字幕一区二区三区视频| 欧美午夜精品一区二区蜜桃 | 美女视频一区二区三区| 国产精品成人免费| 欧美变态口味重另类| 色伊人久久综合中文字幕| 国产呦精品一区二区三区网站 | 国产日韩高清在线| 欧美日本一道本| 成人网页在线观看| 日本中文字幕不卡| 亚洲免费观看高清在线观看| 欧美videofree性高清杂交| 91欧美激情一区二区三区成人| 久久精品国产澳门| 午夜伊人狠狠久久| 亚洲欧美日韩久久精品| 国产日韩欧美不卡| 精品91自产拍在线观看一区| 精品视频全国免费看| 大尺度一区二区| 美洲天堂一区二卡三卡四卡视频| ...av二区三区久久精品| 2023国产精华国产精品| 91麻豆精品国产91久久久使用方法| 91免费版在线看| 粉嫩蜜臀av国产精品网站| 久久国产乱子精品免费女| 亚洲国产成人av| 亚洲欧美日韩国产成人精品影院| 中文子幕无线码一区tr| 精品电影一区二区三区| 69久久99精品久久久久婷婷 | 久久蜜桃一区二区| 91精品欧美福利在线观看| 欧美日韩日日摸| 欧美亚洲日本国产| 91久久奴性调教| 不卡的av在线| 成人国产电影网| av一区二区三区黑人| 成人免费观看av| 91一区二区在线| 91在线国产福利| 99精品在线观看视频| 波多野结衣一区二区三区| bt欧美亚洲午夜电影天堂| 99国产精品99久久久久久| av激情成人网| 色婷婷国产精品| 欧美麻豆精品久久久久久| 欧美高清性hdvideosex| 日韩欧美一二区| 久久久久久**毛片大全| 久久久久久久久蜜桃| 欧美高清在线一区| 依依成人综合视频| 青娱乐精品在线视频| 国产成人免费9x9x人网站视频| 国产美女视频一区| 色悠悠久久综合| 欧美精品日韩综合在线| 精品日产卡一卡二卡麻豆| 亚洲国产精品成人久久综合一区| 国产精品久久久久影院色老大| 亚洲精品第一国产综合野| 丝瓜av网站精品一区二区 | 2021国产精品久久精品| 国产精品国产馆在线真实露脸| 亚洲激情中文1区| 免费成人小视频| 成人午夜在线播放| 欧美日韩高清一区二区不卡| 精品嫩草影院久久| 亚洲男人天堂一区| 美女视频第一区二区三区免费观看网站| 国精产品一区一区三区mba桃花| 91丨九色丨蝌蚪富婆spa| 欧美一二三区在线| 国产精品久久午夜夜伦鲁鲁| 肉肉av福利一精品导航| 国产成人8x视频一区二区| 欧美性猛片aaaaaaa做受| 久久久久久久综合狠狠综合| 亚洲国产日韩a在线播放性色| 久久99精品久久久久久久久久久久 | 国产喷白浆一区二区三区| 一区二区三区小说| 国产一区二区三区香蕉| 欧美日韩在线精品一区二区三区激情 | 欧美日韩成人在线一区| 欧美韩国日本一区| 五月婷婷欧美视频| 99久久久久久99| 久久综合九色综合欧美亚洲| 亚洲成在线观看| 91视视频在线观看入口直接观看www | 制服丝袜亚洲色图| 亚洲色图欧洲色图| 国产乱码精品1区2区3区| 欧美日韩免费在线视频| 国产精品少妇自拍| 九九热在线视频观看这里只有精品| 色香色香欲天天天影视综合网| 久久久精品欧美丰满| 免费看日韩精品| 欧美亚洲一区二区三区四区| 中文字幕中文字幕在线一区| 狠狠狠色丁香婷婷综合激情 | 亚洲综合网站在线观看| 成人av资源站| 久久久777精品电影网影网| 精品一区二区三区免费毛片爱| 欧美综合在线视频| 亚洲小少妇裸体bbw| 欧美自拍偷拍一区| 亚洲综合色婷婷| 色欧美片视频在线观看在线视频| 中文字幕欧美三区| 国产成人午夜视频| 久久久影视传媒| 国产伦精品一区二区三区免费迷| 欧美xxxxxxxx| 精彩视频一区二区三区| 日韩欧美卡一卡二| 精品一区二区三区在线观看国产| 91麻豆精品国产91久久久久| 日韩二区三区四区| 日韩精品一区二区三区视频| 狠狠久久亚洲欧美|