日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一文看懂Shiro权限管理框架!

發布時間:2023/12/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一文看懂Shiro权限管理框架! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 1.JavaWeb中的權限控制
      • 2.權限框架核心知識ACL和RBAC
        • 2.1.ACL和RBAC簡介
        • 2.2主流權限框架介紹
      • 3.Shiro架構和基本概念
        • 3.1.Shiro的4大核心模塊
        • 3.2.Shiro權限控制運行流程
      • 4.Shiro簡單API案例
        • 4.1.項目搭建所需依賴
        • 4.2.Shiro認證簡單實操
        • 4.3.Shiro授權簡單實操
      • 5.安全數據來源Realm
        • 5.1.Realm簡介和繼承關系
        • 5.2.Shiro內置IniRealm權限驗證
        • 5.3.Shiro內置JdbcRealm權限驗證
        • 5.4.Shiro自定義Realm權限配置
        • 5.5.Shiro源碼認證授權流程
      • 6.Shiro權限認證Web案例
        • 6.1.Shiro內置的過濾器
        • 6.2.Shiro的Filter配置路徑
        • 6.3.Shiro數據安全之數據加解密
        • 6.4.Shiro權限控制注解
        • 6.5.Shiro緩存模塊講解
        • 6.6.Shiro Session模塊講解
      • 7.SpringBoot2.x整合Shiro
        • 7.1.數據庫設計
        • 7.2.Maven項目搭建
        • 7.3.編寫查詢用戶全部信息接口
        • 7.4.開發自定義CustomRealm
        • 7.5.ShiroFilterFactoryBean配置
        • 7.6.自定義SessionManager驗證
        • 7.7.API攔截驗證案例
        • 7.8.Shiro密碼加密處理
      • 8.權限控制性能提升
        • 8.1.自定義Shiro Filter過濾器
        • 8.2.Redis整合CacheManager
        • 8.3.Redis整合SessionManager
        • 8.4.ShiroConfig常用的Bean配置
      • 9.分布式應用鑒權方式
        • 9.1.自定義SessionId

1.JavaWeb中的權限控制

(1)什么是權限控制

  • 忽略特別細的概念,比如權限能細分很多種,功能權限,數據權限,管理權限等
  • 理解兩個概念:用戶和資源,讓指定的用戶,只能操作指定的資源(CRUD)

(2)javaweb中怎么處理

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws Exception {HttpServletRequest httpRequest=(HttpServletRequest)request;HttpServletResponse httpResponse=(HttpServletResponse)response;HttpSession session=httpRequest.getSession();if(session.getAttribute("username")!=null){chain.doFilter(request, response);} else {httpResponse.sendRedirect(httpRequest.getContextPath()+"/login.jsp");}}

2.權限框架核心知識ACL和RBAC

2.1.ACL和RBAC簡介

  • ACL:Access Control List 訪問控制列表
    • 以前盛行的一種權限設計,它的核心在于用戶直接和權限掛鉤
    • 優點:簡單易用、開發便捷
    • 缺點:用戶和權限直接掛鉤,導致在授權時的復雜性,比較分散,不便于管理
    • 案例:常見的文件系統權限設計,直接給用戶加權,類似Linux系統中的chmod

  • RBAC:Role Based Access Control
    • 基于角色的訪問控制系統。權限與角色相關聯,用戶通過適當的角色的成員而獲得角色的權限
    • 優點:簡化了用戶與權限的管理,通過對用戶進行分類,使得角色與權限關聯起來
    • 缺點:開發相比ACL復雜
    • 案例:基于RBAC模型的權限驗證框架有Apache Shiro、Spring Security

  • 總結:權限設計不能太過于復雜,否則性能會下降

2.2主流權限框架介紹

(1)什么是Spring Security

  • 官網:https://spring.io/projects/spring-security
Spring Security是一個能夠基于Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI和AOP功能,為應用系統提供聲明式的安全訪問控制功能,減少了企業系統安全控制編寫大量重復代碼的工作。

(2)什么是Apache Shiro

  • 官網:https://github.com/apache/shiro
Apache Shiro是一個強大且易用的java安全框架,執行身份驗證、授權、密碼和會話管理。使用shiro的易于理解的API,可以快速、輕松的執行任何應用程序。
  • 兩個的優缺點
    • Apache Shiro比Spring Security使用更簡單
    • Shiro功能強大、簡潔、靈活,不跟任何的框架或者容器綁定,可以獨立運行
    • SpringSecurity對Spring體系支持比較友好,脫離Spring體系開發很難
    • SpringSecuity支持Oauth鑒權,Shiro需要自己實現

3.Shiro架構和基本概念

3.1.Shiro的4大核心模塊

(1)Shiro的四大核心模塊分為身份認證、授權、會話管理和加密

  • 身份認證
    • Authentication,身份認證,一般就是登錄
  • 授權
    • Authorization,給用戶分配角色或者訪問某些資源的權限
  • 會話管理
    • Session Management,用戶的會話管理員,多數情況下是web Session
  • 加密
    • Cryptogarphy,數據加解密,你如密碼加解密等

(2)Shiro架構圖

3.2.Shiro權限控制運行流程

(1)Shiro常見名稱

  • Subject
    • 我們把用戶或者程序稱為主體,主體去訪問資源或者系統
  • SecurityManager
    • 安全管理器,Subject的認證和授權都在安全管理器下進行
  • Authenticator
    • 認證器,主要負責Subject的認證
  • Realm
    • 數據域,Shiro和安全數據的連接器,好比jdbc連接數據庫;通過realm獲取認證授權的相關信息
  • Authorizer
    • 授權器,主要負責Subject的授權,控制subject擁有的角色或者權限
  • Cryptography
    • 加解密,Shiro包含易于使用和理解的數據加密方法,簡化了很多復雜的API
  • CacheManager
    • 緩存管理器,比如認證或者授權信息,通過緩存進行管理,提高性能
  • SessionManager
    • 會話管理器,大多數是web session
  • SessionDAO
    • SessionDAO即會話,是對session會話的一套接口,比如要將session存儲到數據庫。

4.Shiro簡單API案例

4.1.項目搭建所需依賴

  • 環境準備:maven3.5+jdk8+springboot+idea
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <!--mysql starter 注意一定要把runtime去掉--> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> </dependency> <!--測試模塊starter--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope> </dependency> <!--阿里巴巴數據源--> <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.6</version> </dependency> <!--shiro相關依賴包--> <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.0</version> </dependency>

4.2.Shiro認證簡單實操

(1)Shiro的認證流程

  • 創建Security Manager:Security Manager是用來提供安全服務的,所以在做shiro認證的時候要先創建此對象
  • 主題Subject提交請求給Security Manager
  • Security Manager調用Authenticator組件做認證
  • Authenticator通過Realm來從數據源中獲取認證數據

(2)編碼測試

@SpringBootTest public class Test{//聲明SecurityManagerDefaultSecurityManager securityManager = new DefaultSecurityManager();//聲明RealmSimpleAccountRealm accountRealm = new SimpleAccountRealm();@BeforeTestpublic void init(){accountRealm.addAccount("lixiang","123456");accountRealm.addAccount("lisi","123456");//構建環境securityManager.setRealm(accountRealm);}@Testpublic void test(){SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernameAndPasswordToken token = new UsernameAndPasswordToken("lixiang","123456");subject.login(token);System.out.println("認證結果:"+subject.isAuthenticated());} }

(3)測試結果

4.3.Shiro授權簡單實操

(1)常用API

//是否有對應角色 subject.hasRole("root")//獲取subject名 subject.getPrincipal()//檢查是否有對應的角色,無返回值,直接在SecurityManager里面進行判斷 subject.checkRole("admin")//檢查是否有對應的角色 subject.hasRole("admin")//退出登錄 subject.logout();

(2)編碼實操

@Testvoid contextLoads() {SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("lixiang","123456");subject.login(usernamePasswordToken);System.out.println("認證結果:"+subject.isAuthenticated());System.out.println("獲取subject主體的唯一標識:"+subject.getPrincipal());//檢查是否有對應角色,無返回值,直接在SecurityManager里面進行判斷subject.checkRole("admin");//檢查是否有對應的角色System.out.println("是否有對應角色:"+subject.hasRole("admin"));//退出登錄subject.logout();System.out.println("認證結果:"+subject.isAuthenticated());}

5.安全數據來源Realm

5.1.Realm簡介和繼承關系

  • Realm的作用:Shiro從Realm中獲取安全的數據
  • Realm中的兩個概念:
    • principal:主體的標識,可以有多個,但是必須要有一個唯一性的,常見的用戶名、手機號、郵箱
    • credential:訪問憑證,一般就是密碼
  • 如果要自定義Realm,繼承AuthorizingRealm

  • Realm:頂級接口,所有類的父接口
  • CachingRelam:帶有緩存功能的Realm抽象類
  • AuthenticatingRealm:帶有認證功能的Realm抽象類
  • AuthorizingRealm:帶有授權功能的Realm抽象類
  • SimpleAccountRealm:提供一些簡單的Realm認證
  • TextConfigurationRealm:提供文本形式的Realm認證
  • IniRealm和PropertiesRealm:TextConfigurationRealm的子類,細化文本驗證方式
  • JdbcRealm:與數據庫交互的Realm認證
  • DefaultLdapRealm:根據LDAP進行身份驗證

5.2.Shiro內置IniRealm權限驗證

(1)新建shiro.ini文本文件,編寫規則

#用戶模塊,對應用戶名、密碼、角色,多個角色之間用逗號隔開 [users] lixiang = 123456,user zhangsan = 123456,admin,root#權限模塊,對應角色名稱、對應權限,多個權限用,分隔 [roles] user = video:find,video:buy admin = video:* root = *

(2)測試編碼

@Test public void test(){//創建IniSecurityManagerFactory工廠實例,注意這塊一定要是shiro下的包//IniSecurityManagerFactory這個類已經廢棄了,這里只做驗證Factory<SecurityManager> factory = new IniSecurityManagerFactory();//獲取工廠實例SecurityManager securityManager = factory.getInstance();//將securityManager設置到當前運行環境當中SecurityUtils.setSecurityManager(securityManager);//獲取Subject對象Subject subject = SecurityUtils.getSubject();//創建登錄TokenUsernameAndPasswordToken token = new UsernameAndPasswordToken("lixiang","123456");//驗證subject.login(token);//判斷是否有對應角色System.out.print("判斷是否有對應角色:"+subject.hasRole("admin"));//判斷是否有對應的權限System.out.print("判斷是否有對應權限:"+subject.isPermitted("video:find"));//判斷是否有對應的權限,無返回值,如果檢驗不通過則拋出異常//checkPermission("find:video")}

5.3.Shiro內置JdbcRealm權限驗證

(1)配置jdbcrealm.ini文件,注意這塊一定要是ANSI格式否則運行會拋錯

#注意 文件格式必須為ini,編碼為ANSI#聲明Realm,指定realm類型 jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm#配置數據源 #dataSource=com.mchange.v2.c3p0.ComboPooledDataSourcedataSource=com.alibaba.druid.pool.DruidDataSource# mysql-connector-java 5 用的驅動url是com.mysql.jdbc.Driver,mysql-connector-java6以后用的是com.mysql.cj.jdbc.Driver dataSource.driverClassName=com.mysql.cj.jdbc.Driver#避免安全警告 dataSource.url=jdbc:mysql://120.76.62.13:3606/xdclass_shiro?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falsedataSource.username=testdataSource.password=Xdclasstest#指定數據源 jdbcRealm.dataSource=$dataSource#開啟查找權限, 默認是false,不會去查找角色對應的權限,坑!!!!! jdbcRealm.permissionsLookupEnabled=true#指定SecurityManager的Realms實現,設置realms,可以有多個,用逗號隔開 securityManager.realms=$jdbcRealm
  • 如果編碼不是ANSI格式

(2)驗證

配置文件中 jdbcRealm.permissionsLookupEnabled=true 一定要設置成true,默認是false不會去校驗角色

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-sdIHQpbi-1667452035146)(images/5.2(3)].jpg)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TjSb8TpI-1667452035146)(images/5.2(4)].jpg)

@Testvoid contextLoads() {//創建SecurityManager工廠Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbcrealm.ini");//拿到工廠SecurityManager securityManager = factory.getInstance();//將securityManager設置到當前運行環境當中SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("jack","123");subject.login(token);System.out.println("認證結果:"+subject.isAuthenticated());System.out.println("是否有對應的角色:"+subject.hasRole("user"));//查詢是否有權限,無返回值,沒有則拋異常//subject.checkPermission("video:delete");//查詢是否有權限,有返回值System.out.println(subject.isPermitted("video:delete"));}

5.4.Shiro自定義Realm權限配置

(1)自定義Realm步驟

(1)創建一個類,繼承AuthorizingRealm->AuthenticatingRealm->CachingRealm->Realm (2)重寫授權方法:doGetAuthorizationInfo(進行權限校驗的時候會調用) (3)重寫認證方法:doGetAuthenticationInfo(當用戶登陸的時候會調用)

(2)對象介紹

  • UsernamePasswordToken : 對應就是 shiro的token中有Principal和Credential
  • UsernameAndPasswordToken->HostAuthenticationToken->AuthenticationToken
  • SimpleAuthorizationInfo:代表用戶角色權限信息
  • SimpleAuthenticationInfo:代表該用戶的認證信息

(3)編寫自定義的Realm類

public class CustomRealm extends AuthorizingRealm {//userprivate final static Map<String,String> userMaps = new HashMap<>();{userMaps.put("lixiang","123");userMaps.put("lisi","123");}//roles - > permissionprivate final static Map<String,Set<String>> permissionMaps = new HashMap<>();{Set<String> set1 = new HashSet<>();Set<String> set2 = new HashSet<>();set1.add("video:find");set1.add("video:buy");set2.add("video:add");set2.add("video:delete");permissionMaps.put("lixiang",set1);permissionMaps.put("lisi",set2);}//user -> roleprivate final Map<String,Set<String>> roleMap = new HashMap<>();{Set<String> set1 = new HashSet<>();Set<String> set2 = new HashSet<>();set1.add("role1");set1.add("role2");set2.add("root");roleMap.put("jack",set1);roleMap.put("xdclass",set2);}/*** 進行權限驗證的時候調用* @param principals* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {System.out.println("進行權限驗證doGetAuthorizationInfo");String username = principals.getPrimaryPrincipal().toString();Set<String> permissions = getPermissionsfromDB(username);Set<String> roles = getRolesfromDB(username);SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();simpleAuthorizationInfo.setRoles(roles);simpleAuthorizationInfo.setStringPermissions(permissions);return simpleAuthorizationInfo;}/*** 通過用戶名查找角色* @param username* @return*/private Set<String> getRolesfromDB(String username) {return roleMap.get(username);}/*** 通過用戶名查找權限* @param username* @return*/private Set<String> getPermissionsfromDB(String username) {return permissionMaps.get(username);}/*** 進行身份驗證的時候調用* @param token* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println(" 進行身份驗證doGetAuthenticationInfo");String username = token.getPrincipal().toString();String pwd = getPwdfromDB(username);if("".equals(pwd) || pwd == null){return null;}SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,pwd,this.getName());return simpleAuthenticationInfo;}private String getPwdfromDB(String username) {return userMaps.get(username).toString();} }

(4)測試

SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("lixiang","123"); //登錄 subject.login(token); //唯一標識 System.out.println("用戶名:"+subject.getPrincipal()); System.out.println("是否有對應的角色:"+subject.hasRole("role1")); System.out.println("是否有對應的權限:"+subject.isPermitted("video:find"));

5.5.Shiro源碼認證授權流程

認證流程:

  • subject.login(token)
  • DelegatingSubject.login(token)
  • AuthenticatingSecurityManager.authenticate(token)
  • AbstractAuthenticator.authenticate(token)
  • ModulearRealmAuthenticator.doAuthenticate(token)
  • ModulearRealmAuthenticator.doSingleRealmAuthentication(token)
  • AuthenticatingRealm.getAuthenticationInfo(token)

鑒權流程:

  • subject.checkRole(“admin”)
  • DelegatingSubject.checkRole()
  • AuthorizingSecurityManager.checkRole()
  • ModulatRealmAuthorizer.checkRole()
  • AuthorizingReaim,hasRole()
  • AuthorizingRealm.doGetAuthorizationInfo()

6.Shiro權限認證Web案例

6.1.Shiro內置的過濾器

  • 核心過濾器類:DefaultFilter,配置那個路徑對應那個攔截器進行處理
authc:org.apache.shiro.web.filter.authc.FromAuthenticationFilter - 需要認證登錄才能訪問 user:org.apache.shiro.web.filter.authc.UserFilter - 用戶攔截器,表示必須存在用戶 anon:org.apache.shiro.web.filter.authc.AnonymousFilter - 匿名攔截器,不需要登錄即可訪問的資源,匿名用戶或者游客,一般用于過濾靜態資源 roles:org.apache.shiro.web.filter.authz.RolesAuthorizationFilter - 角色授權攔截器,驗證用戶是否擁有角色。 - 參數可以寫多個,多個參數時寫roles["admin","user"],當多個參數時必須每個參數都通過才算通過。 perms:org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter - 權限授權攔截器,驗證用戶是否擁有權限 - 參數可寫多個,和角色多個是一致的 authcBasic:org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter - httpBasic身份驗證攔截器 logout:org.apache.shiro.web.filter.authc.LogoutFilter - 退出攔截器,執行后會執行跳轉到shiroFilterFactoryBean.setLoginUrl()設置的url port:org.apache.shiro.web.filter.authz.PortFilter - 端口攔截器,可通過的端口 ssl:org.apache.shiro.web.filter.authz.SslFilter - ssl攔截器,只有請求協議是https才能通過

6.2.Shiro的Filter配置路徑

  • 路徑支持通配符,完整匹配,注意匹配符不包括分隔符"/"
  • 路徑通配符支持?、*、**,注意通配符匹配不包括目錄分隔符"/"
  • * 可以匹配所有。不加 * 可以進行前綴匹配,但多個冒號就需要多個 * 來匹配
URL權限采取第一次匹配優先的方式,優先匹配靠前的規則 ?:匹配一個字符,如/user? 匹配/user3,但不匹配/user/ *:匹配0個或多個字符串,如/add*,匹配/addtest,但不匹配/add/1 ** : 匹配路徑中的零個或多個路徑,如 /user/** 將匹 配 /user/xxx 或 /user/xxx/yyy例子 /user/**=filter1 /user/add=filter2請求 /user/add 命中的是filter1攔截器
  • 性能問題:通配符比字符串匹配會復雜點,所以性能也會稍弱,推薦使用字符匹配方式

6.3.Shiro數據安全之數據加解密

(1)為啥要加解密

  • 明文數據容易泄露,比如密碼銘文存儲,萬一泄露則會造成嚴重的后果

(2)什么是散列算法

  • 一般叫hash,簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數,適合存儲密碼,比如MD5

(3)什么是salt(鹽)

  • 如果直接通過散列函數得到的加密數據,容易被對應解密網站暴力破解,一般會在應用層序里面加特殊的自動進行處理,比如用戶id等等,唯一標識的東西。

(4)Shiro里面CredentialsMatcher,用來驗證密碼是否正確

源碼:AuthenticatingRealm -> assertCredentialsMatch()

(5)自定義驗證規則

一般會自定義驗證規則@Beanpublic HashedCredentialsMatcher hashedCredentialsMatcher(){HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();//散列算法,使用MD5算法;hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列的次數,比如散列兩次,相當于 md5(md5("xxx"));hashedCredentialsMatcher.setHashIterations(2);return hashedCredentialsMatcher;}

6.4.Shiro權限控制注解

@RequiresRoles(value={"admin","editor"},logical=Logical.AND) 需要角色admin和editor兩個角色同時滿足@RequiresRoles(value={"admin","editor"},logical=Logical.OR) 需要角色admin或editor兩個角色其中一個滿足@RequiresAuthentication 已經授過權,調用Subject.isAuthenticated()返回true@RequiresUser 身份驗證或者通過記 住我登錄的

查用API

subject.hasRole("xxx") subject.isPermitted("xxx") subject.isPermittedAll("xxx","xxx") subject.checkRole("xxx")

6.5.Shiro緩存模塊講解

  • AuthenticatingRealm 及 AuthorizingRealm 分別提供了對AuthenticationInfo 和 AuthorizationInfo 信息的緩存.


6.6.Shiro Session模塊講解

(1)什么是session會話

用戶和程序直接的鏈接,程序可以根據session識別到哪個用戶,和javaweb中的session類似

(2)什么是會話管理器SessionManager

  • 會話管理器管理所有subject的所有操作,是shiro的核心組件
  • 核心方法
//開啟一個session Session start(SessionContext context) //指定key獲取session Session getSession(SessionKey key)

(3)SessionDao會話存儲/持久化

  • SessionDAO

    • AbstractSessionDAO
      • CachingSessionDAO
        • EnterpeiseCacheSessionDAO
      • MemorySessionDAO
  • 核心方法

//創建 Serializable create(Session session) //獲取 Session readSession(Serializable sessionId) throws UnknownSessionException //更新 void update(Session session) //刪除,會話過期時調用 void delete(Session session) //獲取活躍的session Collection<Session> getActiveSessions() RememberMe 1.Cookie寫到客戶端并保存 2.通過調用subject.login()前,設置 token.setRememberMe(true) - subject.isAuthenticated() 表示用戶進行了身份驗證登錄的,即Subject.login 進行了登錄 - subject.isRemembered() 表示用戶是通過RememberMe登錄的 - subject.isAuthenticated()==true,則 subject.isRemembered()==false, 兩個互斥 - 總結:特殊頁面或者API調用才需要authc進行驗證攔截,該攔截器會判斷用戶是否是通過

7.SpringBoot2.x整合Shiro

7.1.數據庫設計

  • user表
CREATE TABLE `user` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`username` varchar(128) DEFAULT NULL COMMENT '用戶名',`password` varchar(256) DEFAULT NULL COMMENT '密碼',`create_time` datetime DEFAULT NULL,`salt` varchar(128) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
  • role表
CREATE TABLE `role` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(128) DEFAULT NULL COMMENT '名稱',`description` varchar(64) DEFAULT NULL COMMENT '描述',PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
  • user_role表
CREATE TABLE `user_role` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`role_id` int(11) DEFAULT NULL,`user_id` int(11) DEFAULT NULL,`remarks` varchar(64) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
  • permission表
CREATE TABLE `permission` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(128) DEFAULT NULL COMMENT '名稱',`url` varchar(128) DEFAULT NULL COMMENT '接口路徑',PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
  • role_permission表
CREATE TABLE `role_permission` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`role_id` int(11) DEFAULT NULL,`permission_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

7.2.Maven項目搭建

創建SpringBoot項目,引入依賴,配置數據庫

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--阿里巴巴druid數據源--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.6</version></dependency><!--spring整合shiro--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url></repository></repositories><pluginRepositories><pluginRepository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots></pluginRepository><pluginRepository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url></pluginRepository></pluginRepositories> #==============================數據庫相關配置======================================== spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://192.168.10.88:3306/rbac_shiro?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username =root spring.datasource.password =123456 #使用阿里巴巴druid數據源,默認使用自帶的 #spring.datasource.type =com.alibaba.druid.pool.DruidDataSource #開啟控制臺打印sql mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl# mybatis 下劃線轉駝峰配置,兩者都可以 #mybatis.configuration.mapUnderscoreToCamelCase=true mybatis.configuration.map-underscore-to-camel-case=true

7.3.編寫查詢用戶全部信息接口

(1)實體類編寫

  • User
/*** 用戶表*/ public class User {private int id;private String username;private Date createTime;private String salt;private List<Role> roleList; }
  • Role
/*** 角色表*/ public class Role {private int id;private String name;private String description;private List<Permission> permissionList; }
  • UserRole
/*** 用戶角色中間表*/ public class UserRole {private int id;private int userId;private int roleId; }
  • Permission
/*** 權限表*/ public class Permission {private int id;private String name;private String url; }
  • RolePermission
/*** 權限角色中間表*/ public class RolePermission {private int id;private int roleId;private int permissionId; }

(2)Mapper編寫

  • UserMapper
public interface UserMapper {@Select("select * from user where username = #{username}")User findByUsername(@Param("username") String username);@Select("select * from user where id = #{id}")User findById(@Param("id") int id);@Select("select * from user where username = #{username} and password = #{pwd}")User findByUsernameAndPwd(@Param("username") String username,@Param("pwd") String pwd); }
  • RoleMapper
public interface RoleMapper {@Select("select * from user_role where user_id = #{userId}")List<UserRole> findRolesByUserId(@Param("userId") int userId);@Select("select * from role where id = #{roleId}")List<Role> findRolesByRoleId(@Param("roleId") int roleId);}
  • PermissionMapper
public interface PermissionMapper {@Select("select * from permission where id = #{roleId}")List<Permission> findPermissionsByRoleId(@Param("roleId") int roleId); }

(3)UserService編寫

  • UserService
public interface UserService {/*** 獲取用戶全部信息,包括角色權限* @param username* @return*/User findAllUserInfoByUsername(String username);/*** 獲取用戶基本信息* @param userId* @return*/User findSimpleUserInfoById(int userId);/*** 獲取用戶基本信息* @param username* @return*/User findSimpleUserInfoByUsername(String username); }
  • UserServiceImpl
@Service public class UserServiceImpl implements UserService {@Autowiredprivate RoleMapper roleMapper;@Autowiredprivate UserMapper userMapper;@Autowiredprivate PermissionMapper permissionMapper;@Overridepublic User findAllUserInfoByUsername(String username) {User user = userMapper.findByUsername(username);List<UserRole> userRoles = roleMapper.findRolesByUserId(user.getId());List<Role> roles = new ArrayList<>();for (UserRole role : userRoles) {roles = roleMapper.findRolesByRoleId(role.getRoleId());for (Role x : roles) {x.setPermissionList(permissionMapper.findPermissionsByRoleId(x.getId()));}}user.setRoleList(roles);return user;}@Overridepublic User findSimpleUserInfoById(int userId) {return userMapper.findById(userId);}@Overridepublic User findSimpleUserInfoByUsername(String username) {return userMapper.findByUsername(username);} }

(5)controller編寫

@RestController @RequestMapping("/user") public class UserController {@Autowiredprivate UserService userService;@GetMapping("/find_user")public Object findUserInfo(@RequestParam("username") String username){return userService.findAllUserInfoByUsername(username);} }

(6)測試

7.4.開發自定義CustomRealm

  • 繼承 AuthorizingRealm
  • 重寫 doGetAuthorizationInfo
  • 重寫 doGetAuthenticationInfo
public class CustomRealm extends AuthorizingRealm {@Autowiredprivate UserService userService;/*** 用戶鑒權的時候會調用* @param principals* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {System.out.println("鑒權 doGetAuthorizationInfo");String username = (String)principals.getPrimaryPrincipal();User userInfo = userService.findAllUserInfoByUsername(username);//將角色,權限放到對應的兩個String類型集合中List<String> stringRoleList = new ArrayList<>();List<String> stringPermissionList = new ArrayList<>();List<Role> roleList = userInfo.getRoleList();for (Role role : roleList) {stringRoleList.add(role.getName());List<Permission> permissionList = role.getPermissionList();for (Permission permission : permissionList) {if(permission!=null){stringPermissionList.add(permission.getName());}}}//拿到對應的角色集合,權限集合,封裝SimpleAuthorizationInfo對象添加SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();simpleAuthorizationInfo.addRoles(stringRoleList);simpleAuthorizationInfo.addStringPermissions(stringPermissionList);return simpleAuthorizationInfo;}/*** 用戶認證登錄的時候會調用* @param token* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("認證 doGetAuthenticationInfo");//從token中拿到usernameString username = (String)token.getPrincipal();User userInfo = userService.findAllUserInfoByUsername(username);//獲取密碼String password = userInfo.getPassword();if(password == null || "".equals(password)){return null;}//密碼不為空,說明認證成功,封裝SimpleAuthenticationInfo對象,參數:用戶名,密碼,class.getNamereturn new SimpleAuthenticationInfo(username,userInfo.getUsername(),this.getClass().getName());} }

7.5.ShiroFilterFactoryBean配置

  • shiroFilterFactoryBean-》
    • SecurityManager-》
      • CustomSessionManager
      • CustomRealm-》hashedCredentialsMatcher
  • SessionManager
    • DefaultSessionManager: 默認實現,常用于javase
    • ServletContainerSessionManager: web環境
    • DefaultWebSessionManager:常用于自定義實現
@Configuration public class ShiroConfig {/*** 設置shiroFilter* @param securityManager* @return*/@Beanpublic ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){System.out.println("執行 ShiroFilterFactoryBean.shiroFilter()");ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//設置securityManagershiroFilterFactoryBean.setSecurityManager(securityManager);//設置登錄成功后訪問的路徑shiroFilterFactoryBean.setLoginUrl("/pub/need_login");//設置登錄成功后訪問的urlshiroFilterFactoryBean.setSuccessUrl("/");//設置無權限訪問的接口,未授權無法訪問接口shiroFilterFactoryBean.setUnauthorizedUrl("/pub/not_permit");//攔截器路徑配置,注意這里一定要用LinkedHashMap,HashMap會出現偶爾無法攔截的情況Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();//設置過濾器//登出過濾器,用戶退出時調用filterChainDefinitionMap.put("/logout","logout");//匿名過濾器,游客模式filterChainDefinitionMap.put("/pub/**","anon");//登錄過濾器,用戶只有登錄才能訪問filterChainDefinitionMap.put("/authc/**","authc");//管理員角色才能訪問filterChainDefinitionMap.put("/admin/**","roles[admin]");//指定權限才能訪問filterChainDefinitionMap.put("/video/update","perms[video_update]");filterChainDefinitionMap.put("/**","authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}/*** 注入securityManager,設置Realm和SessionManager* @return*/@Beanpublic SecurityManager securityManager(){DefaultSecurityManager securityManager = new DefaultSecurityManager();securityManager.setRealm(customRealm());//注意如果不是前后端分離的項目就不需要設置sessionManagersecurityManager.setSessionManager(customSessionManager());return securityManager;}/*** 設置散列算法* @return*/@Beanpublic HashedCredentialsMatcher hashedCredentialsMatcher(){HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();//設設置散列算法,md5hashedCredentialsMatcher.setHashAlgorithmName("md5");//設置散列次數hashedCredentialsMatcher.setHashIterations(2);return hashedCredentialsMatcher;}/*** 注入自定義的Realm* @return*/@Beanpublic CustomRealm customRealm(){CustomRealm customRealm = new CustomRealm();customRealm.setCredentialsMatcher(hashedCredentialsMatcher());return customRealm;}/*** 注入自定義的SessionManager* @return*/@Beanpublic CustomSessionManager customSessionManager(){CustomSessionManager customSessionManager = new CustomSessionManager();//超時時間,默認30分鐘不操作就會過期,單位豪秒customSessionManager.setGlobalSessionTimeout(20000);return customSessionManager;} }

7.6.自定義SessionManager驗證

public class CustomSessionManager extends DefaultWebSessionManager {private static final String TOKEN="token";//調用父類構造方法,以防后續有人修改構造,空構造覆蓋,會出問題public CustomSessionManager() {super();}@Overrideprotected Serializable getSessionId(ServletRequest request, ServletResponse response) {String sessionId = WebUtils.toHttp(request).getHeader(TOKEN);//如果sessionId不為空,就調用自定義的邏輯,如果為空就調用父類的方法if(sessionId!=null){//調用shiro內部的校驗,檢測sessionId是否存在,是否過期request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId);request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);return sessionId;}else{return super.getSessionId(request,response);}} }

7.7.API攔截驗證案例

(1)AdminController

@RestController @RequestMapping("/admin") public class AdminController {@RequestMapping("/order")public JsonData findOrder(){Map<String,String> recordMap = new HashMap<>();recordMap.put("SpringBoot入門到高級實戰","300元");recordMap.put("Cloud微服務入門到高級實戰","877元");recordMap.put("分布式緩存Redis","990元");return JsonData.buildSuccess(recordMap);}}

(2)LogoutController

@RestController public class LogoutController {@RequestMapping("/logout")public JsonData logout(){String username = (String)SecurityUtils.getSubject().getPrincipal();if(username!=null){SecurityUtils.getSubject().logout();return JsonData.buildSuccess("logout成功");}return JsonData.buildError("logout失敗");}}

(3)OrderController

@RestController @RequestMapping("/authc") public class OrderController {@RequestMapping("/save")public JsonData findMyPlayRecord(){Map<String ,String> recordMap = new HashMap<>();recordMap.put("SpringBoot入門到高級實戰","第8章第1集");recordMap.put("Cloud微服務入門到高級實戰","第4章第10集");recordMap.put("分布式緩存Redis","第10章第3集");return JsonData.buildSuccess(recordMap);}}

(4)pubController

@RestController @RequestMapping("/pub") public class PubController {@RequestMapping("/need_login")public JsonData needLogin(){return JsonData.buildSuccess("溫馨提示:請使用對應的賬號登錄",-2);}@RequestMapping("not_permit")public JsonData notPermit(){return JsonData.buildSuccess("溫馨提示:拒絕訪問,沒權限",-3);}@RequestMapping("/index")public JsonData index(){List<String> videoList = new ArrayList<>();videoList.add("Mysql零基礎入門到實戰 數據庫教程");videoList.add("Redis高并發高可用集群百萬級秒殺實戰");videoList.add("Zookeeper+Dubbo視頻教程 微服務教程分布式教程");videoList.add("2019年新版本RocketMQ4.X教程消息隊列教程");videoList.add("微服務SpringCloud+Docker入門到高級實戰");return JsonData.buildSuccess(videoList);}@PostMapping("/login")public JsonData login(@RequestBody UserQuery userQuery, HttpServletRequest request, HttpServletResponse response){Subject subject = SecurityUtils.getSubject();System.out.println("userQuery:"+userQuery);Map<String,Object> info = new HashMap<>();try {UsernamePasswordToken token = new UsernamePasswordToken(userQuery.getUsername(),userQuery.getPwd());subject.login(token);info.put("session_id",subject.getSession().getId());return JsonData.buildSuccess(info,"登錄成功");}catch (Exception e){info.put("session_id",subject.getSession().getId());return JsonData.buildError("賬號或密碼錯誤");}} }

(5)VideoController

@RestController @RequestMapping("/video") public class VideoController {@RequestMapping("/update")public JsonData updateVideo(){return JsonData.buildSuccess("video 更新成功");}}

(6)用戶角色權限分配圖

(7)測試


7.8.Shiro密碼加密處理

@SpringBootTest class RbacShiroApplicationTests {@Testvoid contextLoads() {//加密算法String hashName = "md5";//密碼明文String pwd = "123456";//加密函數,使用shiro自帶的SimpleHash hash = new SimpleHash(hashName, pwd, null, 2);System.out.println(hash);}}

8.權限控制性能提升

8.1.自定義Shiro Filter過濾器

(1)shiro默認的roles過濾器存在的問題

(2)自定義過濾器類,繼承AuthorizationFilter

public class CustomRolesAuthorizationFilter extends AuthorizationFilter {@Overridepublic boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {Subject subject = getSubject(request, response);String[] rolesArray = (String[]) mappedValue;if (rolesArray == null || rolesArray.length == 0) {//no roles specified, so nothing to check - allow access.return true;}Set<String> roles = CollectionUtils.asSet(rolesArray);//filterChainDefinitionMap.put("/admin/**","roles[admin,root]")// shiro配置角色默認是與的關系,需要都滿足,這里改成或的關系,只要有其中一個即可for (String role : roles) {if (subject.hasRole(role)){return true;}}return false;} }

(3)ShiroConfig中配置自定義過濾器

//設置自定義過濾器 Map<String, Filter> filterMap = new HashMap<>(); filterMap.put("customRolesFilter",new CustomRolesAuthorizationFilter()); shiroFilterFactoryBean.setFilters(filterMap);

8.2.Redis整合CacheManager

  • Redis整合CacheManager為了提高性能,避免每次都去庫查

(1)加入shiro-redis依賴(shiro和redis整合的jar包)

<!--shiro整合redis--> <dependency><groupId>org.crazycake</groupId><artifactId>shiro-redis</artifactId><version>3.1.0</version> </dependency>

(2)ShiroConfig中配置,RedisManager,RedisCacheManager,SecruityManager

/*** 加入RedisManager*/public RedisManager getRedisManager(){RedisManager redisManager = new RedisManager();redisManager.setHost("192.168.10.88");redisManager.setPort(6379);return redisManager;}/*** 配置RedisCacheManager*/public RedisCacheManager cacheManager(){RedisCacheManager redisCacheManager = new RedisCacheManager();redisCacheManager.setRedisManager(getRedisManager());//設置過期時間,單位秒redisCacheManager.setExpire(60);return redisCacheManager;}

(3)改造現有邏輯自定義的Realm

doGetAuthorizationInfo 方法 原有:String username = (String)principals.getPrimaryPrincipal();User user = userService.findAllUserInfoByUsername(username);改為User newUser = (User)principals.getPrimaryPrincipal();User user = userService.findAllUserInfoByUsername(newUser.getUsername());doGetAuthenticationInfo方法 原有: return new SimpleAuthenticationInfo(username, user.getPassword(), this.getClass().getName());改為 return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());

8.3.Redis整合SessionManager

(1)加入SessionDAO的配置

/*** 配置SessionDAO*/public RedisSessionDAO sessionDAO(){RedisSessionDAO sessionDAO = new RedisSessionDAO();//設置RedisManagersessionDAO.setRedisManager(getRedisManager());return sessionDAO;}

(2)自定義的sessionManager中設置sessionDAO

//設置Session持久化,RedisSessionManager //注意:如果不設置過期時間,redis中存儲也和shiro中session的默認過期時間保持一致 customSessionManager.setSessionDAO(sessionDAO());

(3)注意傳輸的實體類都要實現Serializable接口,否則會報錯

8.4.ShiroConfig常用的Bean配置

(1)LifecycleBeanPostProcessor:管理shiro一些bean的生命周期,即bean初始化與銷毀

@Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor(); }

(2)AuthorizationAttributeSourceAdvisor:加入注解的使用,不加入這個AOP注解不生效(@RequiresGuest)

@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());return authorizationAttributeSourceAdvisor; }

(3)DefaultAdvisorAutoProxyCreator:用來掃描上下文尋找的所有Advistor(通知器),將符合條件的Advisor應用到切入點的Bean中,需要在LifecycleBeanPostProcessor創建后才可以創建

@Bean @DependsOn("lifecycleBeanPostProcessor") public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();defaultAdvisorAutoProxyCreator.setUsePrefix(true);return defaultAdvisorAutoProxyCreator; }

9.分布式應用鑒權方式

9.1.自定義SessionId

  • Shiro 默認的sessionid生成 類名 SessionIdGenerator
  • 創建CustomSessionIdGenerator類,實現 SessionIdGenerator 接口的方法
/** * 自定義session持久化 * @return */ public RedisSessionDAO redisSessionDAO(){ RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); redisSessionDAO.setRedisManager(getRedisManager()); //設置sessionid生成器 redisSessionDAO.setSessionIdGenerator(new CustomSessionIdGenerator()); //設置自定義的sessionIdGenerator return redisSessionDAO; }

總結

以上是生活随笔為你收集整理的一文看懂Shiro权限管理框架!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

成人免费视频网址 | 国产激情电影综合在线看 | 日本久久久影视 | 国产成人久久77777精品 | 午夜精品久久久久久中宇69 | 免费看片成人 | 久久国产亚洲视频 | 五月天.com | 国产又粗又猛又黄视频 | 96国产在线 | av在线播放不卡 | 欧美一级电影免费观看 | 亚洲一二三区精品 | 午夜电影久久久 | 日本久久免费视频 | 手机在线日韩视频 | 国产视频不卡一区 | 精品成人国产 | 久久精品亚洲综合专区 | 亚洲视频 一区 | 超碰在线98 | 久久免费毛片 | 日韩成人精品在线观看 | 国内精品在线观看视频 | 97精品国产91久久久久久 | 国产一级做a | 日韩三区在线 | 成人免费观看完整版电影 | 国产精品日韩在线播放 | 国产精品视频永久免费播放 | 国产免费av一区二区三区 | 国产91在线观看 | 97超碰人人澡人人 | 在线观看成人福利 | 亚洲黄色av网址 | 欧美午夜理伦三级在线观看 | 久久99精品国产一区二区三区 | 91精品综合在线观看 | 成人免费观看在线视频 | 右手影院亚洲欧美 | av一级片在线观看 | 国产免费区 | 日韩高清在线一区二区 | 亚洲视频在线观看 | 在线观看av不卡 | 日韩综合色 | 免费成人在线观看 | 成年人在线免费视频观看 | 日本中文字幕免费观看 | 日本久久久久久久久 | 亚洲人成网站精品片在线观看 | 91传媒视频在线观看 | 色噜噜在线观看 | 精品嫩模福利一区二区蜜臀 | 国产精品一区一区三区 | av中文字幕在线电影 | 成人中心免费视频 | 91香蕉国产在线观看软件 | 国产精品久久久久久电影 | 射射射av | a在线观看国产 | 亚洲欧洲精品一区二区 | 欧美日韩网址 | 中文字幕av全部资源www中文字幕在线观看 | www.狠狠操.com | 91精品国产乱码在线观看 | av不卡中文字幕 | 日韩电影在线观看一区 | 欧美色噜噜 | 91香蕉久久 | 天天干天天操天天入 | 日韩视频免费在线观看 | 久久精品一级片 | 91激情视频在线观看 | 五月天电影免费在线观看一区 | 国产成人99av超碰超爽 | 亚洲精品成人在线 | 97超碰在线久草超碰在线观看 | 日本一区二区三区免费观看 | 成片视频免费观看 | 精品一区二区亚洲 | 亚洲精品国产第一综合99久久 | 伊人五月婷 | 欧美性护士 | 三级黄色理论片 | 91视频在线免费下载 | 国产一级片免费观看 | 日韩高清 一区 | 中文字幕一区在线 | 国产不卡视频在线 | 黄色三级在线 | 在线观看日韩精品视频 | 在线导航av | 亚洲mv大片欧洲mv大片免费 | 狠狠色丁香久久综合网 | 色在线国产 | 69精品在线| 国产成人一区二区三区久久精品 | 日韩中文字幕免费看 | 麻豆久久精品 | 美女网站视频色 | 一个色综合网站 | 99精品国产兔费观看久久99 | 成人午夜精品福利免费 | 97操操操| 欧美日韩精品影院 | 亚洲精品国产精品乱码不99热 | 久草香蕉在线 | 国产精品免费成人 | 亚洲一级二级 | 国产精品一区在线观看你懂的 | 少妇搡bbbb搡bbb搡忠贞 | 国产免费精彩视频 | 国产精品高潮久久av | 黄网站www | 免费看的av片 | 婷婷激情站 | 一区免费在线 | 国内视频 | 精品中文字幕在线观看 | 中文字幕高清 | 欧美激情综合五月色丁香小说 | 最近日本mv字幕免费观看 | 青青河边草观看完整版高清 | 91九色在线视频观看 | av软件在线观看 | www.com久久| 久久国产精品久久精品 | 97精品国产91久久久久久久 | 免费v片 | 波多野结衣在线播放一区 | 久久国产免费看 | 激情久久小说 | 激情深爱 | 国产高清中文字幕 | 久久久午夜影院 | 五月天久久狠狠 | 超碰av在线| av福利在线免费观看 | 亚洲狠狠婷婷综合久久久 | 亚洲一区黄色 | 公与妇乱理三级xxx 在线观看视频在线观看 | 中文字幕一二三区 | 一区二区 不卡 | 久久高清免费 | 国产精品va | 久久久网站 | 操操日| 午夜色婷婷 | 国产一区二区精 | 亚洲毛片久久 | 久久精品视频在线观看 | 狠狠干天天色 | 麻花豆传媒mv在线观看 | 一区二区精 | 激情欧美一区二区三区 | 免费网站在线观看成人 | 国产在线a | 国产91粉嫩白浆在线观看 | 国产夫妻性生活自拍 | 久草在线视频精品 | 正在播放国产91 | 欧美人牲| 中国一级片免费看 | 国产黄视频在线观看 | 麻豆久久久久久久 | 久久久久久高潮国产精品视 | 91在线你懂的 | 在线观看国产91 | 日本大片免费观看在线 | 9999精品视频 | 超碰97人人在线 | 国产精品黄 | 奇米网8888| 国产精品欧美久久久久无广告 | 另类五月激情 | 丝袜护士aⅴ在线白丝护士 天天综合精品 | 久久国产精品第一页 | 五月婷婷在线视频观看 | 夜夜夜夜爽| 久久久麻豆视频 | 最近免费中文字幕 | 久久 国产一区 | 久草在线视频网 | 国产精品理论在线观看 | 久久国产成人午夜av影院潦草 | 久久中文网 | 少妇性bbb搡bbb爽爽爽欧美 | 亚洲综合导航 | 碰超在线观看 | 91九色视频 | 欧美日韩伦理一区 | 天天操 夜夜操 | 中文字幕观看av | 婷婷综合在线 | 九九九在线观看 | 国产精品精品视频 | 黄色在线观看www | 最新91在线视频 | 免费在线观看黄色网 | 日韩一二三在线 | 操操操av | 国产精品免费在线观看视频 | 亚洲精品乱码白浆高清久久久久久 | 伊人色综合久久天天网 | 99精品视频在线免费观看 | 91九色视频在线播放 | 麻花豆传媒mv在线观看 | 黄网站大全| 亚洲综合小说 | 国精产品999国精产品岳 | 日韩精品一区二区三区电影 | 激情动态| 午夜精品一区二区三区可下载 | 最新av电影网站 | 欧洲在线免费视频 | 中文字幕在线观看视频网站 | 九九热1| 免费在线黄色av | 91精彩视频在线观看 | 一区二区三区视频在线 | www黄色av | 黄色aaa级片| 日韩av一卡二卡三卡 | 精品国产不卡 | a国产精品 | 久久婷婷一区二区三区 | 韩日电影在线免费看 | 日韩视频专区 | 最近中文国产在线视频 | 五月综合| 精品久久一| 久久久精品欧美一区二区免费 | 五月天婷婷免费视频 | 不卡的av | 中文字幕婷婷 | www99久久 | 色婷婷视频在线 | 欧美一性一交一乱 | 欧美日韩大片在线观看 | 在线免费av电影 | 国产三级av在线 | 国产在线资源 | 日韩欧美69| 日韩av手机在线观看 | 精品国产乱码久久久久久天美 | 久久久99久久| 视频在线观看一区 | 国产在线中文 | 中文在线字幕免费观看 | 成人黄色在线看 | 96久久精品| 91成人精品| 精品国产免费一区二区三区五区 | 黄色成人影视 | 美女视频永久黄网站免费观看国产 | 国产精久久久久久久 | 成人一区电影 | 欧美日韩精品在线视频 | 国产伦理久久精品久久久久_ | 天天做天天爽 | 国产黄色精品在线 | 狠狠色丁香婷综合久久 | 国产精品爽爽久久久久久蜜臀 | 国产在线传媒 | 91中文字幕一区 | 亚洲精品国产欧美在线观看 | 亚洲国产精品99久久久久久久久 | 91探花系列在线播放 | 99久久99久久精品国产片果冰 | 亚洲乱码精品久久久 | 91亚色视频在线观看 | 国产黄色精品网站 | 国产特级毛片aaaaaa | 97超碰国产精品女人人人爽 | 中文字幕在线观看国产 | 超碰在线资源 | 中文在线免费视频 | 九九久久精品 | 国产盗摄精品一区二区 | 友田真希x88av | 国产视频69| 97视频免费在线看 | 日韩在线精品一区 | 四虎影视国产精品免费久久 | 国产97视频| 午夜精品福利影院 | 国产黄色高清 | 99久久er热在这里只有精品15 | 日韩三级在线观看 | 涩涩网站在线观看 | 国产黄色片免费观看 | 久久久天堂 | 亚洲男女精品 | 成人a毛片 | 色综合色综合久久综合频道88 | 日韩动漫免费观看高清完整版在线观看 | 天天夜夜亚洲 | 国产无区一区二区三麻豆 | 色久五月| 天天干天天射天天操 | 97视频一区 | 制服丝袜在线91 | av 在线观看 | 一区二区精品在线观看 | 中文字幕在线观看视频免费 | 久精品视频在线观看 | 伊人资源视频在线 | 国产97色| 久久国内精品 | 久久y| 有没有在线观看av | 日韩av一区二区三区 | 国产精品福利一区 | 日日干美女 | 国产中的精品av小宝探花 | 天天艹天天 | 黄色毛片一级片 | 91av视屏| 日韩精品首页 | 久久综合网色—综合色88 | 麻豆国产露脸在线观看 | 爱干视频 | 亚洲 欧洲av | 69视频在线播放 | 日韩美女免费线视频 | 免费h视频 | 亚洲片在线资源 | av免费看网站 | 成人性生交大片免费看中文网站 | 四虎5151久久欧美毛片 | 午夜电影久久 | 玖玖视频国产 | 六月色| 99 国产精品| 欧美吞精| 狠狠躁日日躁狂躁夜夜躁 | 欧美一级电影在线观看 | av综合网址 | 伊人黄色网 | 国产 日韩 中文字幕 | 久草免费手机视频 | 大荫蒂欧美视频另类xxxx | 日韩免费在线观看视频 | 国产高清精品在线观看 | 美女视频黄的免费的 | 最新日韩视频在线观看 | 免费成人在线网站 | 久久夜色电影 | 国产中文字幕网 | 亚洲一区二区视频 | 中文国产在线观看 | 看黄色.com | 婷婷丁香社区 | 亚洲 欧美 日韩 综合 | 亚洲欧洲精品一区二区精品久久久 | 日韩偷拍精品 | 国产一区国产二区在线观看 | 天天射射天天 | 日本福利视频在线 | 国产美女精彩久久 | 91最新地址永久入口 | 国产黑丝一区二区 | 国产精品日韩高清 | 中文字幕在线观看视频一区 | 亚洲婷婷网 | 韩日视频在线 | 欧美天天射 | 天天做日日做天天爽视频免费 | 九九99 | 日日操网站 | 狠狠狠狠狠狠干 | 美女很黄免费网站 | 欧美日韩综合在线 | 国产精品久一 | 国产破处在线播放 | 在线 国产 亚洲 欧美 | 亚洲国产三级在线 | 国产高清在线永久 | 亚洲精品视频在线观看网站 | 麻豆精品在线 | 久久综合九色综合97_ 久久久 | 欧美一级久久久 | 亚洲一区欧美精品 | 久久久国产精品一区二区三区 | 国产精品9区 | 国外成人在线视频网站 | 午夜久久影视 | 亚洲一二视频 | 超碰97人人干 | 欧美性网站 | 欧美色插 | av综合 日韩| 成人禁用看黄a在线 | 国产香蕉97碰碰久久人人 | 天天爽天天射 | 在线观看一级片 | 国产精品淫 | 国产黄色电影 | 天堂入口网站 | 西西人体4444www高清视频 | 亚洲免费av一区二区 | 日韩欧美视频在线播放 | 日韩视频一区二区 | 久99久中文字幕在线 | 亚洲天天做 | 成人黄色电影在线播放 | 黄色高清视频在线观看 | 亚洲精品国产精品国 | a黄色片在线观看 | 国产美女精彩久久 | a色视频| 天天综合导航 | 欧美极度另类性三渗透 | 久久亚洲婷婷 | 成人在线黄色 | 五月天com | 日本性久久 | 韩国av一区二区三区 | 欧美精品一区在线发布 | 91天天操| 中文字幕有码在线观看 | 香蕉视频在线免费 | 伊人超碰在线 | 狠狠干狠狠艹 | 亚洲丝袜一区 | 日日夜精品 | 五月婷av| 一本一道久久a久久精品 | 国产97免费| 色小说在线 | 亚洲精品成人免费 | 婷婷免费视频 | 夜夜视频资源 | 久久这里有| 欧美二区在线播放 | 欧美va天堂在线电影 | 久av在线 | 国语自产偷拍精品视频偷 | 国内精品久久久久影院男同志 | 六月色播 | 久久久999精品视频 国产美女免费观看 | 日日夜夜天天综合 | 丁香花中文在线免费观看 | 国产小视频网站 | 亚洲视频国产 | 欧美福利网站 | 中文字幕免费一区二区 | 婷婷激情五月 | 2023国产精品自产拍在线观看 | 在线中文字幕观看 | 青青草华人在线视频 | 91在线精品视频 | 国产精品久久久久久久久久免费 | 日本久久片| 国产亚洲精品久久久久秋 | 欧美91精品久久久久国产性生爱 | 中文字幕高清在线播放 | 亚洲丝袜中文 | 午夜视频导航 | 精品国产区在线 | 国产日韩欧美在线播放 | 人人爽人人射 | 久久久久女教师免费一区 | 国产日韩欧美视频在线观看 | 国产精品久久久久永久免费看 | 国产永久网站 | 欧美一级欧美一级 | 天堂网一区 | 国产高清第一页 | 婷婷国产视频 | 亚洲 欧美日韩 国产 中文 | 国产毛片aaa | 亚洲精品午夜aaa久久久 | 精品在线亚洲视频 | 五月婷婷在线视频 | 深爱五月网 | 日韩在线二区 | 日韩在线一二三区 | 亚洲第一久久久 | 在线黄色免费av | 亚洲欧美成人在线 | 亚洲国产成人高清精品 | 国产精品毛片一区视频播不卡 | 一区二区三区日韩视频在线观看 | 波多野结衣一区二区 | 日韩精品欧美一区 | 久久国产精品精品国产色婷婷 | 欧美激情视频一二区 | 日韩在线电影一区 | 亚洲精品网址在线观看 | 中文字幕国产精品 | 玖玖999| 久草在线最新免费 | 久久免费中文视频 | 精品日韩在线 | 国产特级毛片aaaaaaa高清 | 欧美日本在线观看视频 | 日韩在线观看第一页 | 日韩在线视频免费观看 | 亚洲精品xxxx | 久草精品免费 | 日韩激情在线 | 成人免费视频网站 | 99精品免费久久久久久久久 | 欧美视频在线观看免费网址 | 久久久久久国产精品免费 | 黄色一级网 | 特黄特色特刺激视频免费播放 | 成人av片免费看 | 天天射,天天干 | 免费视频成人 | av夜夜操| 婷婷丁香在线视频 | 久久亚洲综合国产精品99麻豆的功能介绍 | 国精产品999国精产品视频 | 97国产在线播放 | 99色婷婷 | 亚洲人成人99网站 | 91成人精品一区在线播放 | 人人爽人人爽人人爽 | 日韩欧美视频免费看 | 91在线看| 亚洲国产成人在线 | 中文字幕在线视频国产 | 天天干夜夜干 | 亚洲国产精品一区二区久久,亚洲午夜 | 91在线播 | 国产精品高潮呻吟久久久久 | 欧美男男激情videos | av福利超碰网站 | 成人国产一区二区 | 亚洲国产操 | 国产一区二区三区 在线 | 99久久日韩精品视频免费在线观看 | 在线观看视频国产 | avove黑丝| 国产香蕉97碰碰碰视频在线观看 | av中文字幕在线播放 | 国产视频午夜 | 天天射天天操天天干 | 中文字幕999| 综合网欧美 | 久久精品国产99国产 | 成人一区电影 | 久久免费电影 | 日本黄色免费在线观看 | 天天·日日日干 | 婷婷爱五月天 | 精品久久国产 | www.在线看片.com | 日本一区二区三区免费看 | 欧美一级黄色网 | 亚洲综合爱 | 日韩中文字幕a | 狠狠狠狠狠狠操 | 亚洲乱亚洲乱妇 | 免费黄色看片 | 狠狠干综合 | 天堂va欧美va亚洲va老司机 | 天天干,天天射,天天操,天天摸 | 久久精品超碰 | 一级黄色免费网站 | 丁香免费视频 | 婷婷色网站 | 欧美a级在线 | 国产亚洲在 | 国产一区二区在线播放视频 | 久久久麻豆精品一区二区 | 国产三级精品三级在线观看 | 亚洲免费在线观看视频 | 中午字幕在线 | 日韩电影在线一区 | 在线播放视频一区 | 免费亚洲片 | 黄网站免费久久 | 国产精品99精品久久免费 | 亚洲jizzjizz日本少妇 | 国产黄在线看 | 97在线观看免费观看 | 国产中文字幕在线免费观看 | 中文一区在线观看 | 亚洲精品在线观看的 | 四虎成人免费观看 | 在线亚洲精品 | 国产99久久久国产 | 97免费在线观看视频 | 免费看黄色毛片 | 亚洲黄色av | 亚洲精品资源在线观看 | 国产亚洲综合精品 | 欧美日韩在线播放一区 | 国产韩国日本高清视频 | 狠狠色丁香婷综合久久 | 亚洲另类视频在线 | 色在线网站 | 国产视频一区二区在线播放 | 亚洲精品国产精品久久99热 | 曰韩精品| 成人在线播放网站 | 日韩在线免费高清视频 | 天天干 天天摸 天天操 | 在线高清 | 亚洲成av人片在线观看无 | 中文在线亚洲 | 午夜av片 | 日韩欧美高清 | 在线视频在线观看 | 亚洲国产精品一区二区尤物区 | 97av在线 | 激情五月婷婷综合网 | 黄色毛片在线观看 | 色一级片 | 国产精品一区在线播放 | 久久久精品网 | 果冻av在线| 在线成人小视频 | 在线视频精品 | 色婷婷综合久久久久中文字幕1 | 国产探花| 福利区在线观看 | 欧美激情综合色综合啪啪五月 | 欧美精品在线视频 | 97在线观视频免费观看 | 亚洲综合五月天 | 青青河边草免费直播 | 天天操人人干 | 国产免费嫩草影院 | 亚洲人毛片 | 在线日韩中文 | 久久香蕉电影 | 99久久99久久精品免费 | 天天草天天干天天射 | 高清色免费| 天天色天天爱天天射综合 | 天天人人综合 | 亚洲一区二区三区四区在线视频 | 久久久久久综合 | 久久一区二区三区超碰国产精品 | 国产精品欧美激情在线观看 | 激情综合六月 | 狠狠亚洲 | 999久久国产精品免费观看网站 | 99视频精品 | 亚洲国产无 | 国产一区二区视频在线播放 | 国产精品99久久久久久久久 | 国产黄色在线网站 | 欧美成人xxx | 中文字幕在线观看91 | 五月婷婷综合在线观看 | av色影院| 欧美在线你懂的 | a久久久久久 | 婷婷色中文 | 91网页版在线观看 | av福利在线播放 | 久久久久久久久毛片 | 国内久久看 | 日韩欧美精品一区二区三区经典 | 麻豆传媒视频在线免费观看 | 五月的婷婷 | 亚洲专区视频在线观看 | 国产91丝袜在线播放动漫 | 999抗病毒口服液 | 一本—道久久a久久精品蜜桃 | 欧美怡红院视频 | 久久草在线视频国产 | bayu135国产精品视频 | 欧美福利视频一区 | 91人人澡| 中文免费在线观看 | 99视频精品在线 | 欧美日韩精品影院 | 亚洲尺码电影av久久 | 日韩欧美精品在线观看 | 国产色a在线观看 | 四虎国产精品永久在线国在线 | 国产高清成人 | 久久久久久国产精品亚洲78 | 99视频在线免费看 | 免费看黄在线网站 | 久久新视频 | 免费看黄色小说的网站 | 国产精品欧美一区二区 | 日韩高清观看 | 日韩高清久久 | 久久精品视频国产 | 国内精品久久久久 | 国产精品久久久久久久久久久久 | 日日日视频 | 91在线国内视频 | 精品美女久久久久久免费 | 国产91aaa | 五月天久久综合网 | 一区二区视频播放 | 免费在线观看的av网站 | 国产九九九精品视频 | 亚洲精品在线观看av | 日韩视频精品在线 | 日本一区二区三区免费看 | 成人黄色在线看 | 国产精品系列在线播放 | 久草视频在线资源 | 欧美久久久久久久久久 | 免费看久久 | 国产精品第一页在线 | 日本性高潮视频 | 精品国产免费看 | 一级特黄av| 国产精品成人一区二区 | 国产美女在线精品免费观看 | 亚洲免费视频在线观看 | 视频二区在线 | 国产精品99久久久精品免费观看 | 五月天婷亚洲天综合网鲁鲁鲁 | 在线观看亚洲国产精品 | 国产xvideos免费视频播放 | 五月婷婷综合在线 | 欧美一级视频免费 | 精品国产视频一区 | 中文字幕之中文字幕 | 免费观看www小视频的软件 | 国产精品免费一区二区三区 | 日韩大片在线播放 | 国产在线自| 欧美男男tv网站 | 日韩精品在线免费观看 | 激情网五月| 日韩电影在线观看一区 | 日本黄色黄网站 | 亚洲精品美女在线观看 | 91成人精品一区在线播放69 | 久久精彩免费视频 | 久久综合之合合综合久久 | 五月婷婷丁香在线观看 | 欧美成年网站 | 麻豆成人精品 | 婷婷播播网 | 天天在线视频色 | 开心激情综合网 | 亚洲精品在线免费观看视频 | 三级黄色免费 | 午夜精品久久久久久久久久 | 午夜精品久久久久久 | zzijzzij日本成熟少妇 | 在线天堂v | 在线观看日韩av | 国产精品中文字幕在线播放 | 日韩理论 | 成人av网址大全 | 久久精品爱爱视频 | 久久久久免费精品视频 | 国产精品h在线观看 | 天天操天天射天天舔 | 日韩在线观看视频一区二区三区 | 国产精品一区二区果冻传媒 | 国产99久久久国产精品免费看 | 亚洲经典视频在线观看 | 伊人网综合在线观看 | 亚洲视频中文 | 成年人黄色免费网站 | 91av在线免费看 | 少妇性bbb搡bbb爽爽爽欧美 | 精品无人国产偷自产在线 | 六月丁香婷 | 久久黄视频 | 4438全国亚洲精品在线观看视频 | 亚洲成人软件 | 国产青春久久久国产毛片 | 国产精品成人久久久久久久 | 99久久精品免费看国产 | 免费中文字幕 | 久久精品一二三区 | 国产色道 | 亚洲网久久 | 伊人日日干 | 奇米网网址 | 免费视频一二三区 | 不卡av在线免费观看 | 国产精品自产拍在线观看蜜 | 成人a免费看 | 在线视频精品播放 | 不卡av电影在线 | 中文字幕在线看视频国产中文版 | 久久涩涩网站 | 日韩系列| 伊人天天干 | 久热免费在线观看 | 福利一区在线 | 99在线精品免费视频九九视 | 97色国产 | 91麻豆传媒 | 五月婷婷综合色拍 | 国产精品女同一区二区三区久久夜 | 婷婷爱五月天 | 久久论理 | 久久草 | 999久久久久久 | 视频在线观看一区 | 天天摸天天舔天天操 | 97在线免费视频 | 久久久国产一区二区三区 | 久久精品8| www久久| 国产成人久久精品77777 | 国产精品久久久久av免费 | 国语黄色片 | www九九热 | 国产精品国产三级国产aⅴ无密码 | 中文av网 | 亚洲一级二级三级 | 国产亚洲婷婷 | 久久网站av | 欧美一级大片在线观看 | 手机看片中文字幕 | 精品美女国产在线 | 99久久婷婷国产综合亚洲 | 在线视频18在线视频4k | 天天躁日日躁狠狠 | 男女视频久久久 | 久久免费精品视频 | 四川bbb搡bbb爽爽视频 | 2019免费中文字幕 | 国产夫妻av在线 | 91探花视频 | 亚洲国产精品成人va在线观看 | 黄色小说视频在线 | 日日夜夜草 | 天天综合色网 | 在线免费高清 | 色噜噜狠狠狠狠色综合久不 | 久久人人爽爽 | 激情丁香久久 | 人人天天夜夜 | 玖玖视频精品 | 亚洲专区在线 | 日韩高清精品免费观看 | 日本动漫做毛片一区二区 | 97视频人人澡人人爽 | 色综合天天视频在线观看 | 欧洲视频一区 | 日韩在线观看你懂得 | 国产精品视频区 | 伊人热 | 国产真实精品久久二三区 | www.99热精品 | 亚洲最新av在线网站 | 激情在线免费视频 | 在线观看免费观看在线91 | 国产夫妻av在线 | 在线视频在线观看 | 精品1区2区3区 | 99热高清 | 国内精品久久久久影院男同志 | 青青视频一区 | 日韩一三区| 国产在线视频资源 | 日韩电影久久 | 欧美国产日韩在线视频 | 园产精品久久久久久久7电影 | 97狠狠干| 在线网址你懂得 | 国内三级在线观看 | 成人动漫一区二区 | 欧美成年人在线视频 | 在线看成人av| 亚州精品视频 | 一区二区三区免费在线观看视频 | 91亚洲激情 | 久久免费福利视频 | 色av资源网 | av一级久久 | 国产一区二区三精品久久久无广告 | 久草精品视频在线播放 | 久久69精品 | 日韩在线观看视频在线 | 日韩精品中文字幕久久臀 | 69国产盗摄一区二区三区五区 | 婷婷色5月 | 又黄又刺激又爽的视频 | 521色香蕉网站在线观看 | 91精品视频在线免费观看 | 极品嫩模被强到高潮呻吟91 | 中文字幕亚洲国产 | 色婷婷综合久久久久中文字幕1 | 久久精品一区二区三区国产主播 | 免费福利影院 | 国产中出在线观看 | 久久高清 | 国产在线一区观看 | 国产精品6 | 六月丁香在线视频 | 国产精品久免费的黄网站 | 98超碰人人 | 午夜性生活片 | 激情视频免费观看 | 2019中文| 中文字幕乱码电影 | www,黄视频| 国产免费观看av | 亚洲人成在线观看 | av高清一区二区三区 | 超碰97国产 | 久久人人97超碰国产公开结果 | 天天操天天摸天天干 | 中文资源在线播放 | 免费a网 | 福利视频一区二区 | 久久久久久久久精 | 欧美午夜一区二区福利视频 | 久草免费色站 | 蜜桃麻豆www久久囤产精品 | 免费久久久久久 | 日韩av一区二区在线播放 | 日韩精品首页 | 成人黄色毛片视频 | 久久国产亚洲视频 | 日韩一区二区三区免费视频 | 亚洲成人网av | 国产成人精品久久二区二区 | 国产理论片在线观看 | 综合久久久久久 | 精品久久网 | 免费成人av网站 | 久久资源在线 | 久久久美女 | 欧美国产日韩在线观看 | 婷婷六月丁香激情 | 国产精品毛片久久 | 日本一区二区不卡高清 | 四虎海外影库www4hu | 超碰97免费 | 免费亚洲一区二区 | 2022国产精品视频 | 人人添人人澡人人澡人人人爽 | 精品免费观看 | 久久99久久99精品中文字幕 | 97碰在线 | 国产一区二区在线免费观看 | 99久久精品一区二区成人 | 国产小视频免费在线网址 | 在线观看视频中文字幕 | 久久久久免费精品国产小说色大师 | 久久综合电影 | 国产成人61精品免费看片 | 天天色综合天天 | 午夜国产影院 | 国产手机在线观看视频 | 黄色一级在线观看 | 91片黄在线观看动漫 | 一区二区三区电影 | 国内少妇自拍视频一区 | 区一区二在线 | 97精品国产一二三产区 | 国产99久久久久久免费看 | 日韩视频一区二区 | 一区精品久久 | 婷婷色亚洲 | 日韩av电影中文字幕在线观看 | 国产高清视频免费 | 国产精品不卡在线播放 | 亚洲一区二区三区四区在线视频 | 国产1区2区| 亚洲最大av在线播放 | 欧美日韩网址 | 国产高清精品在线观看 | 婷婷综合视频 | 夜夜躁天天躁很躁波 | 黄色国产高清 | 又黄又爽又刺激 | 骄小bbw搡bbbb揉bbbb | 国产在线久草 | 国产视频 亚洲视频 | 亚洲国产精品电影 | 国产精品涩涩屋www在线观看 | 天天爽天天搞 | 欧美一区二区在线 | 国产黄在线免费观看 | 夜夜夜夜猛噜噜噜噜噜初音未来 | av免费在线观看1 | 成 人 黄 色视频免费播放 | 国产精品久久久久久久av电影 | 国产日韩精品在线 | 中文字幕一区二区三区四区 | 伊人手机在线 | 国产免费高清 | 青草视频在线看 | 国产精品12 | 亚洲免费在线播放视频 | 亚洲最大av网站 | 五月婷婷欧美 | 精壮的侍卫呻吟h | 超碰国产在线播放 | 日韩视频一二三区 | 日日插日日干 | 亚洲国产成人精品久久 | 久久国产91 |