日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

SpringBoot中整合Shiro實現(xiàn)權限管理的示例代碼

瀏覽:32日期:2023-04-26 14:58:24

之前在 SSM 項目中使用過 shiro,發(fā)現(xiàn) shiro 的權限管理做的真不錯,但是在 SSM 項目中的配置太繁雜了,于是這次在 SpringBoot 中使用了 shiro,下面一起看看吧

一、簡介

Apache Shiro是一個強大且易用的Java安全框架,執(zhí)行身份驗證、授權、密碼和會話管理。使用Shiro的易于理解的API,您可以快速、輕松地獲得任何應用程序,從最小的移動應用程序到最大的網(wǎng)絡和企業(yè)應用程序。

三個核心組件:

1、Subject

即“當前操作用戶”。但是,在 Shiro 中,Subject 這一概念并不僅僅指人,也可以是第三方進程、后臺帳戶(Daemon Account)或其他類似事物。它僅僅意味著“當前跟軟件交互的東西”。Subject 代表了當前用戶的安全操作,SecurityManager 則管理所有用戶的安全操作。

2、SecurityManager

它是Shiro 框架的核心,典型的 Facade 模式,Shiro 通過 SecurityManager 來管理內(nèi)部組件實例,并通過它來提供安全管理的各種服務。

3、Realm

Realm 充當了 Shiro 與應用安全數(shù)據(jù)間的“橋梁”或者“連接器”。也就是說,當對用戶執(zhí)行認證(登錄)和授權(訪問控制)驗證時,Shiro 會從應用配置的 Realm 中查找用戶及其權限信息。從這個意義上講,Realm 實質(zhì)上是一個安全相關的 DAO:它封裝了數(shù)據(jù)源的連接細節(jié),并在需要時將相關數(shù)據(jù)提供給 Shiro。當配置 Shiro 時,你必須至少指定一個 Realm,用于認證和(或)授權。配置多個 Realm 是可以的,但是至少需要一個。Shiro 內(nèi)置了可以連接大量安全數(shù)據(jù)源(又名目錄)的 Realm,如 LDAP、關系數(shù)據(jù)庫(JDBC)、類似 INI 的文本配置資源以及屬性文件等。如果缺省的 Realm 不能滿足需求,你還可以插入代表自定義數(shù)據(jù)源的自己的 Realm 實現(xiàn)。

二、整合 shiro

1、引入 maven 依賴

<!-- web支持 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><!-- thymeleaf 模板引擎 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- Shiro 權限管理 --><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.4</version></dependency><!-- 為了能夠在 html 中使用 shiro 的標簽引入 --><dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version></dependency>

我使用的 SpringBoot 版本是 2.3.1,其它依賴自己看著引入吧

2、創(chuàng)建 shiro 配置文件

關于 shiro 的配置信息,我們都放在 ShiroConfig.java 文件中

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.spring.LifecycleBeanPostProcessor;import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.DependsOn;import java.util.LinkedHashMap;import java.util.Map;/** * shiro配置類 */@Configurationpublic class ShiroConfig { /** * 注入這個是是為了在thymeleaf中使用shiro的自定義tag。 */ @Bean(name = 'shiroDialect') public ShiroDialect shiroDialect() { return new ShiroDialect(); } /** * 地址過濾器 * @param securityManager * @return */ @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 設置securityManager shiroFilterFactoryBean.setSecurityManager(securityManager); // 設置登錄url shiroFilterFactoryBean.setLoginUrl('/login'); // 設置主頁url shiroFilterFactoryBean.setSuccessUrl('/'); // 設置未授權的url shiroFilterFactoryBean.setUnauthorizedUrl('/unauthorized'); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); // 開放登錄接口 filterChainDefinitionMap.put('/doLogin', 'anon'); // 開放靜態(tài)資源文件 filterChainDefinitionMap.put('/css/**', 'anon'); filterChainDefinitionMap.put('/img/**', 'anon'); filterChainDefinitionMap.put('/js/**', 'anon'); filterChainDefinitionMap.put('/layui/**', 'anon'); // 其余url全部攔截,必須放在最后 filterChainDefinitionMap.put('/**', 'authc'); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } /** * 自定義安全管理策略 */ @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); /** 設置自定義的relam */ securityManager.setRealm(loginRelam()); return securityManager; } /** * 登錄驗證 */ @Bean public LoginRelam loginRelam() { return new LoginRelam(); } /** * 以下是為了能夠使用@RequiresPermission()等標簽 */ @Bean @DependsOn({'lifecycleBeanPostProcessor'}) public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } @Bean public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager()); return authorizationAttributeSourceAdvisor; }}

上面開放靜態(tài)資源文件,其它博客說的是 **filterChainDefinitionMap.put('/static/**', 'anon');** ,但我發(fā)現(xiàn),我們在 html 文件中引入靜態(tài)文件時,請求路徑根本沒有經(jīng)過 static,thymeleaf 自動默認配置 **static/** 下面就是靜態(tài)資源文件,所以,我們開放靜態(tài)資源文件需要指定響應的目錄路徑

2、登錄驗證管理

關于登錄驗證的一些邏輯,以及賦權等操作,我們都放在 LoginRelam.java 文件中

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.zyxx.sbm.entity.UserInfo;import com.zyxx.sbm.service.RolePermissionService;import com.zyxx.sbm.service.UserInfoService;import com.zyxx.sbm.service.UserRoleService;import org.apache.shiro.authc.*;import org.apache.shiro.authc.credential.CredentialsMatcher;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;import org.springframework.beans.factory.annotation.Autowired;import java.util.Set;/** * 登錄授權 */public class LoginRelam extends AuthorizingRealm { @Autowired private UserInfoService userInfoService; @Autowired private UserRoleService userRoleService; @Autowired private RolePermissionService rolePermissionService; /** * 身份認證 * * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { // 獲取基于用戶名和密碼的令牌:實際上這個authcToken是從LoginController里面currentUser.login(token)傳過來的 UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; //根據(jù)用戶名查找到用戶信息 QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(); queryWrapper.eq('account', token.getUsername()); UserInfo userInfo = userInfoService.getOne(queryWrapper); // 沒找到帳號 if (null == userInfo) { throw new UnknownAccountException(); } // 校驗用戶狀態(tài) if ('1'.equals(userInfo.getStatus())) { throw new DisabledAccountException(); } // 認證緩存信息 return new SimpleAuthenticationInfo(userInfo, userInfo.getPassword(), ByteSource.Util.bytes(userInfo.getAccount()), getName()); } /** * 角色授權 * * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { UserInfo authorizingUser = (UserInfo) principalCollection.getPrimaryPrincipal(); if (null != authorizingUser) { //權限信息對象info,用來存放查出的用戶的所有的角色(role)及權限(permission) SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); //獲得用戶角色列表 Set<String> roleSigns = userRoleService.listUserRoleByUserId(authorizingUser.getId()); simpleAuthorizationInfo.addRoles(roleSigns); //獲得權限列表 Set<String> permissionSigns = rolePermissionService.listRolePermissionByUserId(authorizingUser.getId()); simpleAuthorizationInfo.addStringPermissions(permissionSigns); return simpleAuthorizationInfo; } return null; } /** * 自定義加密規(guī)則 * * @param credentialsMatcher */ @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { // 自定義認證加密方式 CustomCredentialsMatcher customCredentialsMatcher = new CustomCredentialsMatcher(); // 設置自定義認證加密方式 super.setCredentialsMatcher(customCredentialsMatcher); }}

以上就是登錄時,需要指明 shiro 對用戶的一些驗證、授權等操作,還有自定義密碼驗證規(guī)則,在第3步會講到,獲取角色列表,權限列表,需要獲取到角色與權限的標識,每一個角色,每一個權限都有唯一的標識,裝入 Set 中

3、自定義密碼驗證規(guī)則

密碼的驗證規(guī)則,我們放在了 CustomCredentialsMatcher.java 文件中

import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;import org.apache.shiro.crypto.hash.SimpleHash;/** * @ClassName CustomCredentialsMatcher * 自定義密碼加密規(guī)則 * @Author Lizhou * @Date 2020-07-10 16:24:24 **/public class CustomCredentialsMatcher extends SimpleCredentialsMatcher { @Override public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; //加密類型,密碼,鹽值,迭代次數(shù) Object tokenCredentials = new SimpleHash('md5', token.getPassword(), token.getUsername(), 6).toHex(); // 數(shù)據(jù)庫存儲密碼 Object accountCredentials = getCredentials(info); // 將密碼加密與系統(tǒng)加密后的密碼校驗,內(nèi)容一致就返回true,不一致就返回false return equals(tokenCredentials, accountCredentials); }}

我們采用的密碼加密方式為 MD5 加密,加密 6 次,使用登錄賬戶作為加密密碼的鹽進行加密

4、密碼加密工具

上面我們自定義了密碼加密規(guī)則,我們創(chuàng)建一個密碼加密的工具類 PasswordUtils.java 文件

import org.apache.shiro.crypto.hash.Md5Hash;/** * 密碼加密的處理工具類 */public class PasswordUtils { /** * 迭代次數(shù) */ private static final int ITERATIONS = 6; private PasswordUtils() { throw new AssertionError(); } /** * 字符串加密函數(shù)MD5實現(xiàn) * * @param password 密碼 * @param loginName 用戶名 * @return */ public static String getPassword(String password, String loginName) { return new Md5Hash(password, loginName, ITERATIONS).toString(); }}

三、開始登錄

上面,我們已經(jīng)配置了 shiro 的一系列操作,從登錄驗證、密碼驗證規(guī)則、用戶授權等等,下面我們就開始登錄,登錄的操作,放在了 LoginController.java 文件中

import com.zyxx.common.consts.SystemConst;import com.zyxx.common.enums.StatusEnums;import com.zyxx.common.kaptcha.KaptchaUtil;import com.zyxx.common.shiro.SingletonLoginUtils;import com.zyxx.common.utils.PasswordUtils;import com.zyxx.common.utils.ResponseResult;import com.zyxx.sbm.entity.UserInfo;import com.zyxx.sbm.service.PermissionInfoService;import io.swagger.annotations.Api;import io.swagger.annotations.ApiImplicitParam;import io.swagger.annotations.ApiImplicitParams;import io.swagger.annotations.ApiOperation;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;import org.apache.shiro.subject.Subject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * @ClassName LoginController * @Description * @Author Lizhou * @Date 2020-07-02 10:54:54 **/@Api(tags = '后臺管理端--登錄')@Controllerpublic class LoginController { @Autowired private PermissionInfoService permissionInfoService; @ApiOperation(value = '請求登錄頁面', notes = '請求登錄頁面') @GetMapping('login') public String init() { return 'login'; } @ApiOperation(value = '請求主頁面', notes = '請求主頁面') @GetMapping('/') public String index() { return 'index'; } @ApiOperation(value = '登錄驗證', notes = '登錄驗證') @ApiImplicitParams({ @ApiImplicitParam(name = 'account', value = '賬號', required = true), @ApiImplicitParam(name = 'password', value = '密碼', required = true), @ApiImplicitParam(name = 'resCode', value = '驗證碼', required = true), @ApiImplicitParam(name = 'rememberMe', value = '記住登錄', required = true) }) @PostMapping('doLogin') @ResponseBody public ResponseResult doLogin(String account, String password, String resCode, Boolean rememberMe, HttpServletRequest request, HttpServletResponse response) throws Exception { // 驗證碼 if (!KaptchaUtil.validate(resCode, request)) { return ResponseResult.getInstance().error(StatusEnums.KAPTCH_ERROR); } // 驗證帳號和密碼 Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(account, password); // 記住登錄狀態(tài) token.setRememberMe(rememberMe); try { // 執(zhí)行登錄 subject.login(token); // 將用戶保存到session中 UserInfo userInfo = (UserInfo) subject.getPrincipal(); request.getSession().setAttribute(SystemConst.SYSTEM_USER_SESSION, userInfo); return ResponseResult.getInstance().success(); } catch (UnknownAccountException e) { return ResponseResult.getInstance().error('賬戶不存在'); } catch (DisabledAccountException e) { return ResponseResult.getInstance().error('賬戶已被凍結'); } catch (IncorrectCredentialsException e) { return ResponseResult.getInstance().error('密碼不正確'); } catch (ExcessiveAttemptsException e) { return ResponseResult.getInstance().error('密碼連續(xù)輸入錯誤超過5次,鎖定半小時'); } catch (RuntimeException e) { return ResponseResult.getInstance().error('未知錯誤'); } } @ApiOperation(value = '登錄成功,跳轉(zhuǎn)主頁面', notes = '登錄成功,跳轉(zhuǎn)主頁面') @PostMapping('success') public String success() { return 'redirect:/'; } @ApiOperation(value = '初始化菜單數(shù)據(jù)', notes = '初始化菜單數(shù)據(jù)') @GetMapping('initMenu') @ResponseBody public String initMenu() { return permissionInfoService.initMenu(); } @ApiOperation(value = '退出登錄', notes = '退出登錄') @GetMapping(value = 'loginOut') public String logout() { Subject subject = SecurityUtils.getSubject(); subject.logout(); return 'login'; }}

當執(zhí)行 subject.login(token); 時,就會進入我們在 第二步中第二條登錄驗證中,對用戶密碼、狀態(tài)進行檢查,對用戶授權等操作,登錄的密碼,一定是通過密碼加密工具得到的,不然驗證不通過

四、頁面權限控制

我們本次使用的是 thymeleaf 模板引擎,我們需要在 html 文件中加入以下內(nèi)容

<!DOCTYPE html><html xmlns='http://www.w3.org/1999/xhtml' xmlns:th='http://www.thymeleaf.org' xmlns:shiro='http://www.pollix.at/thymeleaf/shiro'>

引入了 thymeleaf 的依賴,以及 shiro 的依賴,這樣我們就能在 html 文件中使用 thymeleaf、shiro 的標簽了

例如:

1、判斷當前用戶有無此權限,通過權限標識

<button shiro:hasPermission='user_info_add'><i class='layui-icon'>&#xe654;</i> 新增 </button>

2、與上面相反,判斷當前用戶無此權限,通過權限標識,沒有時驗證通過

<button shiro:lacksPermission='user_info_add'><i class='layui-icon'>&#xe654;</i> 新增 </button>

3、判斷當前用戶有無以下全部權限,通過權限標識

<button shiro:hasAllPermissions='user_info_add'><i class='layui-icon'>&#xe654;</i> 新增 </button>

4、判斷當前用戶有無以下任一權限,通過權限標識

<button shiro:hasAnyPermissions='user_info_add'><i class='layui-icon'>&#xe654;</i> 新增 </button>

5、判斷當前用戶有無此角色,通過角色標識

<a shiro:hasRole='admin' href='http://m.b3g6.com/bcjs/admin.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' rel='external nofollow' >Administer the system</a>

6、與上面相反,判斷當前用戶無此角色,通過角色標識,沒有時驗證通過

<a shiro:lacksRole='admin' href='http://m.b3g6.com/bcjs/admin.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' rel='external nofollow' >Administer the system</a>

7、判斷當前用戶有無以下全部角色,通過角色標識

<a shiro:hasAllRoles='admin,role1,role2' href='http://m.b3g6.com/bcjs/admin.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' rel='external nofollow' >Administer the system</a>

8、判斷當前用戶有無以下任一角色,通過角色標識

<a shiro:hasAnyRoles='admin,role1,role2' href='http://m.b3g6.com/bcjs/admin.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' rel='external nofollow' >Administer the system</a>

到此這篇關于SpringBoot中整合Shiro實現(xiàn)權限管理的示例代碼的文章就介紹到這了,更多相關SpringBoot整合Shiro權限內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲精品一区二区在线播放∴| 国产免费成人| 亚洲欧美日韩国产一区二区| 欧美成人基地 | 欧美韩一区二区| 日韩中文字幕不卡| 亚洲欧美视频一区二区三区| 美女国产一区| 热久久久久久| 国产麻豆精品| 日本在线高清| 欧美~级网站不卡| 欧美日韩精品一本二本三本| 亚洲欧美视频| 国产精品a久久久久| 91视频久久| 在线一区免费| 日本va欧美va瓶| 91欧美在线| 精品理论电影在线| 日韩**一区毛片| 亚洲黄色中文字幕| 黑丝美女一区二区| 亚洲精品美女91| 视频在线不卡免费观看| 国产一区亚洲| 人人爱人人干婷婷丁香亚洲| 日韩理论视频| 亚洲性视频在线| 97se综合| 国产欧美丝祙| 日韩理论片av| **爰片久久毛片| 成人日韩在线| 日韩中文在线播放| 亚洲深夜av| 国产精品一区二区中文字幕| 五月综合激情| 卡一精品卡二卡三网站乱码| 日韩一级欧洲| 日本在线高清| 欧美91在线|欧美| 亚洲精品影视| 久久91视频| 黄页网站一区| 韩国一区二区三区视频| 国产色综合网| 欧美1级日本1级| 午夜宅男久久久| 日韩欧美另类一区二区| 日韩av三区| 98精品视频| 国产精品1区在线| 国产丝袜一区| 日韩av资源网| 日韩激情一二三区| 亚洲三级在线| 亚洲天堂免费| 蜜臀av性久久久久蜜臀aⅴ流畅 | 亚洲最新av| 免费黄网站欧美| 最新国产拍偷乱拍精品| 精品亚洲成人| 久久久亚洲欧洲日产| 久久国产精品美女| 国产毛片精品| 国产精品jk白丝蜜臀av小说| 国产乱子精品一区二区在线观看| 日韩高清欧美激情| 国产探花在线精品| 日本欧美一区| 国产精品麻豆成人av电影艾秋 | 免费在线看一区| 亚洲精选成人| 国产亚洲精品美女久久| 国产精品香蕉| 激情欧美丁香| 老鸭窝亚洲一区二区三区| 久久精品播放| 免费人成黄页网站在线一区二区| 亚洲一区二区三区久久久| 日韩av成人高清| 国产在线观看www| 午夜在线一区| 免费在线日韩av| 国产精品88久久久久久| 九九在线精品| 黄色免费成人| 国产劲爆久久| 麻豆传媒一区二区三区| 久久一二三区| 免费一级欧美片在线观看网站| 久久久久久婷| 香蕉视频成人在线观看| 国产麻豆一区二区三区| 深夜福利视频一区二区| 首页亚洲欧美制服丝腿| 久久精品免视看国产成人| 久久精品动漫| 国产欧美亚洲一区| 国产亚洲激情| 成人高清一区| 伊人精品一区| 久久99久久人婷婷精品综合| 伊人久久大香线蕉av超碰演员| 国产精品玖玖玖在线资源| 欧美日韩精品一本二本三本| 精品网站aaa| av在线最新| 无码日韩精品一区二区免费| 青青草视频一区| 亚洲成人精选| 国产 日韩 欧美 综合 一区| 日韩中文字幕亚洲一区二区va在线| 精品一区av| 欧美一级二级三级视频| 蜜桃av一区二区| 国产va在线视频| 国产欧美一区二区精品久久久| 国产精品免费看| 999久久久国产精品| 国产一区二区三区不卡视频网站 | 1024精品一区二区三区| 亚洲图片久久| 日韩一级网站| 神马午夜久久| 首页国产精品| 国产在线不卡一区二区三区| 国产精品一区二区99| 97久久亚洲| 奇米777国产一区国产二区| 一区二区三区四区在线观看国产日韩| 亚洲一本视频| 欧美特黄一区| 美女精品在线| 在线观看视频免费一区二区三区| 91成人在线网站| 亚洲电影在线一区二区三区| 成人污污视频| 欧美影院三区| 蜜臀久久99精品久久久久久9| 日韩三级久久| 久久伊人久久| 亚洲手机在线| 午夜亚洲福利| 精品不卡一区| 女人av一区| 91福利精品在线观看| 精品精品久久| 91精品国产自产在线观看永久∴ | 在线免费观看亚洲| 在线精品视频一区| 国产精品一线天粉嫩av| 精品一二三区| 红桃视频国产一区| 欧美日韩a区| 国产麻豆久久| 亚洲另类av| 日韩国产一区二区三区| 免费在线看一区| 精品国产欧美| 午夜久久av| 亚洲成人av观看| 欧美日韩精品一区二区三区视频| 福利一区二区| 老色鬼久久亚洲一区二区| 国产欧美69| 老色鬼久久亚洲一区二区| 色偷偷色偷偷色偷偷在线视频| 久久久亚洲欧洲日产| 午夜电影亚洲| 国产亚洲一卡2卡3卡4卡新区| 国产精品九九| 国产精品毛片久久| 亚洲一二av| 99久久亚洲精品| 国产成人精品亚洲线观看 | 国产精品99精品一区二区三区∴| 国内精品福利| 欧美1区2区3| 日本综合视频| 最新国产精品视频| 亚洲永久字幕| 激情久久中文字幕| 国产亚洲一区二区手机在线观看| 国产精品v一区二区三区| 亚洲精品影视| 四虎精品一区二区免费| 亚洲欧美久久精品| 性色一区二区| 久久激情一区| 国产亚洲一区二区三区啪| 免费日韩av片| 免费欧美日韩| 国户精品久久久久久久久久久不卡 | 高清一区二区| 超碰99在线| 色在线视频观看| 久久精品观看| 午夜久久tv|