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

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

SpringBoot中整合Shiro實現權限管理的示例代碼

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

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

一、簡介

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

三個核心組件:

1、Subject

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

2、SecurityManager

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

3、Realm

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

二、整合 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、創建 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'); // 開放靜態資源文件 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; }}

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

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; //根據用戶名查找到用戶信息 QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(); queryWrapper.eq('account', token.getUsername()); UserInfo userInfo = userInfoService.getOne(queryWrapper); // 沒找到帳號 if (null == userInfo) { throw new UnknownAccountException(); } // 校驗用戶狀態 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; } /** * 自定義加密規則 * * @param credentialsMatcher */ @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { // 自定義認證加密方式 CustomCredentialsMatcher customCredentialsMatcher = new CustomCredentialsMatcher(); // 設置自定義認證加密方式 super.setCredentialsMatcher(customCredentialsMatcher); }}

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

3、自定義密碼驗證規則

密碼的驗證規則,我們放在了 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 * 自定義密碼加密規則 * @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; //加密類型,密碼,鹽值,迭代次數 Object tokenCredentials = new SimpleHash('md5', token.getPassword(), token.getUsername(), 6).toHex(); // 數據庫存儲密碼 Object accountCredentials = getCredentials(info); // 將密碼加密與系統加密后的密碼校驗,內容一致就返回true,不一致就返回false return equals(tokenCredentials, accountCredentials); }}

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

4、密碼加密工具

上面我們自定義了密碼加密規則,我們創建一個密碼加密的工具類 PasswordUtils.java 文件

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

三、開始登錄

上面,我們已經配置了 shiro 的一系列操作,從登錄驗證、密碼驗證規則、用戶授權等等,下面我們就開始登錄,登錄的操作,放在了 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); // 記住登錄狀態 token.setRememberMe(rememberMe); try { // 執行登錄 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('密碼連續輸入錯誤超過5次,鎖定半小時'); } catch (RuntimeException e) { return ResponseResult.getInstance().error('未知錯誤'); } } @ApiOperation(value = '登錄成功,跳轉主頁面', notes = '登錄成功,跳轉主頁面') @PostMapping('success') public String success() { return 'redirect:/'; } @ApiOperation(value = '初始化菜單數據', notes = '初始化菜單數據') @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'; }}

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

四、頁面權限控制

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

<!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://www.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://www.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://www.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://www.b3g6.com/bcjs/admin.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' rel='external nofollow' >Administer the system</a>

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

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲精选91| 免费欧美在线视频| 丝袜美腿高跟呻吟高潮一区| 日韩成人高清| 国产成人精品福利| 国产精品欧美大片| 日韩高清一区在线| 亚洲在线成人| 欧美亚洲精品在线| 天堂中文在线播放| 成人国产精品| 加勒比视频一区| 国产欧美二区| 久久都是精品| 一区免费在线| 亚洲激情av| 激情婷婷综合| 久久亚洲精品中文字幕蜜潮电影| 神马久久午夜| 四虎国产精品免费观看| 欧美国产另类| 国产视频一区二区在线播放| 亚洲精一区二区三区| 久久亚洲电影| 男人的天堂久久精品| 一区二区自拍| 9国产精品视频| 99xxxx成人网| 日韩在线中文| 麻豆视频在线看| 久久91导航| 久久高清精品| 蜜臀久久99精品久久一区二区| 久久视频国产| 欧美日韩日本国产亚洲在线| 免费视频亚洲| 在线视频精品| 亚洲免费福利一区| 99亚洲精品| 中文视频一区| 日韩三级视频| 国产精品久久久网站| 毛片不卡一区二区| 福利一区二区三区视频在线观看| 鲁鲁在线中文| 久久国产电影| 亚洲免费中文| 日韩精品视频在线看| 国产精品久久| 极品av在线| 久久精品青草| 免费看欧美美女黄的网站| 亚洲1区在线| 国产精品一站二站| 精品亚洲精品| 欧美日韩中文字幕一区二区三区| 亚洲精品国产偷自在线观看| 亚洲精品高潮| 97成人在线| 免费一级欧美片在线观看网站| 国产精品网址| 私拍精品福利视频在线一区| 在线成人直播| 亚州精品视频| 欧美自拍一区| a日韩av网址| 欧美大黑bbbbbbbbb在线| 国产一区二区三区久久| 丝袜亚洲另类欧美| 久久精品国产福利| 免费在线成人网| 日韩影院二区| 国产精品一线天粉嫩av| 999久久久国产精品| 97成人超碰| 中文日韩欧美| 成人日韩在线| 免费在线观看一区| 一区二区电影| 日韩欧美一区二区三区在线观看| 日韩欧美美女在线观看| 欧美日韩中文字幕一区二区三区 | 动漫av一区| 午夜久久av | 麻豆mv在线观看| 日韩和欧美一区二区三区| 午夜日韩福利| 成人片免费看| 毛片不卡一区二区| 日韩区一区二| 欧美中文字幕| 在线日韩中文| 日韩欧美一区二区三区在线视频| 国产精品资源| 免费在线欧美视频| 欧美日韩在线二区| 日韩国产一区| 国产成人精品福利| 国产精品99久久久久久董美香| 亚洲日韩视频| 亚洲一区国产一区| 国产精品99免费看| 欧美日韩精品免费观看视欧美高清免费大片| 国产乱码精品一区二区三区四区| 香蕉久久久久久久av网站| 亚洲91视频| 日韩欧美自拍| 日韩.com| 国产一区二区三区四区大秀| 欧美日韩亚洲一区三区| 日韩高清中文字幕一区| 日韩中文字幕| 日韩午夜视频在线| 无码日韩精品一区二区免费| 亚洲精品精选| 亚洲精品精选| 日本综合精品一区| 午夜天堂精品久久久久| 亚洲九九精品| 日本一区二区三区中文字幕| 亚洲精品一级| 亚洲精品女人| 亚洲bt欧美bt精品777| 午夜久久av| 日本不卡高清| 日韩va欧美va亚洲va久久| 亚洲bt欧美bt精品777| 亚州精品视频| 日韩av不卡在线观看| 亚洲伊人精品酒店| 亚洲精品少妇| 亚洲日韩中文字幕一区| 日韩综合一区二区三区| 日韩av网站在线免费观看| 欧美一区免费| 久久影视三级福利片| 国产精选在线| 亚洲国产专区校园欧美| 性欧美长视频| 亚洲青青久久| 欧美一区91| 美女久久久久久| 国产高清不卡| 国产视频一区欧美| 亚洲人成网站在线在线观看| 日韩国产在线观看| 欧美国产日本| 日韩精品电影| 欧美日韩国产在线观看网站| 香蕉久久久久久久av网站| 日韩福利在线观看| 精品视频97| 欧美色图一区| 石原莉奈在线亚洲二区| 亚洲毛片一区| 国产精品99久久免费| 日韩欧美综合| 天堂成人免费av电影一区| 日韩国产欧美视频| 色婷婷色综合| 日韩一级欧洲| 欧美日韩一区二区高清| 日韩成人三级| 男人的天堂久久精品| 国产精品多人| 亚洲大片在线| 日韩1区2区日韩1区2区| 成人午夜毛片| 国产视频一区三区| 国产欧美日韩亚洲一区二区三区| 国产乱码午夜在线视频| 免费久久99精品国产| 精品伊人久久久| 亚洲欧美日韩一区在线观看| 欧美激情在线精品一区二区三区| 久久人人精品| 亚洲精品护士| 国产在线观看www| 免费精品视频在线| 国产一区福利| 免费在线观看不卡| 久久天堂影院| 久久不射网站| 高清av一区| 久久aⅴ国产紧身牛仔裤| 开心激情综合| 亚洲欧美日韩国产一区| 久久久国产精品网站| 国产精品毛片| 国产不卡精品| 亚洲精品伊人| 欧美aa在线观看| 久久国产三级精品| 亚洲午夜黄色| 国产精品国产三级在线观看| 亚洲高清久久| 免费在线亚洲欧美| 一区二区三区四区日韩| 夜鲁夜鲁夜鲁视频在线播放| 天堂精品久久久久|