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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Shiro从入门到实战(整合进SpringBoot)

發(fā)布時間:2023/12/16 javascript 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Shiro从入门到实战(整合进SpringBoot) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 一、Shiro是什么?
  • 二、Shiro 的功能介紹
    • 1.基本功能點(diǎn)
    • 2.功能點(diǎn)介紹
  • 三、Shiro 的架構(gòu)
    • 1.Shrio的應(yīng)用層面架構(gòu)
    • 2.Shiro的核心架構(gòu)
  • 四、Shiro入門案例
    • 1.shiro.ini
    • 2.Quickstart.class
  • 五、Shiro實(shí)戰(zhàn)-整合進(jìn)Spring Boot
    • 1.創(chuàng)建父工程shiroDemo
    • 2.創(chuàng)建shiroAuth子模塊(Maven)
    • 3.代碼結(jié)構(gòu)講解
    • 4.各個類詳細(xì)講解
    • 5.補(bǔ)充多Realm認(rèn)證


前言

這篇文章主要是為了輔助記憶Shiro的,下面的代碼主要復(fù)用了我看的一個視頻里面的代碼:https://www.bilibili.com/video/BV1Tf4y1w7Yo,所以有些地方如果不太了解的話可以去看看這個視頻,不過這個視頻有些地方可能有點(diǎn)繞,所以如果有shiro基礎(chǔ),只是想回顧一下的話,我覺得看這篇文章應(yīng)該就可以很快回顧起來,如果沒有shiro基礎(chǔ)的話可能還是得跟著視頻一起看。由于本人水平有限,所以可能有些地方寫的不是很好,有發(fā)現(xiàn)什么問題的話,大家都可以指出來,共同進(jìn)步!


一、Shiro是什么?

  • Apache Shiro是Java的一個安全(權(quán)限)框架。
  • Shiro可以非常容易的開發(fā)出足夠好的應(yīng)用,其不僅可以用在JavaSE環(huán)境,也可以用在JavaEE環(huán)境。
  • Shiro可以完成:認(rèn)證、授權(quán)、加密、會話管理、與Web集成、緩存等。

Shiro官網(wǎng):http://shiro.apache.org/

二、Shiro 的功能介紹

1.基本功能點(diǎn)

2.功能點(diǎn)介紹

  • Authentication(認(rèn)證):判斷一個用戶是否為合法用戶的處理過程。最常用的身份認(rèn)證方式是核對用戶輸入的用戶名和密碼是否與系統(tǒng)中存儲的用戶名和密碼一致。還可以采用指紋和人臉識別等方式認(rèn)證;
  • Authorization(授權(quán)):訪問控制或權(quán)限驗(yàn)證,簡單來說就是給不同的角色授予不同的權(quán)限,以及驗(yàn)證某個已認(rèn)證的用戶是否擁有某個權(quán)限;
  • Session Manager(會話管理):管理所有用戶登錄后的會話信息。用戶登錄后用Subject.getSession() 即可獲取會話,在沒有退出之前,用戶的所有信息都在會話中;會話可以是普通JavaSE環(huán)境,也可以是Web環(huán)境的;
  • Cryptography(加密):保護(hù)數(shù)據(jù)的安全性,如密碼加密存儲到數(shù)據(jù)庫,而不是明文存儲;
  • Web Support(Web支持):可以非常容易的集成到Web環(huán)境;
  • Caching(緩存):用戶登錄后,其用戶信息、擁有的角色/權(quán)限不必每次去查,直接從緩存中獲取,這樣可以提高效率;
  • Concurrency:Shiro支持多線程應(yīng)用的并發(fā)驗(yàn)證,即如在一個線程中開啟另一個線程,能把權(quán)限自動傳播過去;
  • Testing:提供測試支持;
  • Run As:允許一個用戶假裝為另一個用戶(如果他們允許)的身份進(jìn)行訪問;
  • Remember Me(記住我):非常常見的功能,即一次登錄后,下次無需登錄;

三、Shiro 的架構(gòu)

1.Shrio的應(yīng)用層面架構(gòu)

  • Subject:任何直接與應(yīng)用代碼交互的對象。Subject代表了當(dāng)前“用戶”,這個用戶不具體指代某個人,只要與當(dāng)前應(yīng)用交互的任何東西都是Subject,如第三方服務(wù)、網(wǎng)絡(luò)爬蟲、機(jī)器人等;所有Subject實(shí)例都必須被綁定到一個SecurityManager上,SecurityManager才是實(shí)際的執(zhí)行者;
  • SecurityManager(安全管理器):與安全有關(guān)的操作都會與SecurityManager進(jìn)行交互;管理著所有的Subject;它是Shiro的核心,負(fù)責(zé)與Shiro的其他組件進(jìn)行交互,相當(dāng)于SpringMVC中DispatcherServlet的角色;
  • Realm:擔(dān)當(dāng)Shiro和你的應(yīng)用程序的安全數(shù)據(jù)之間的“橋梁”或“連接器”。Shiro可以從Realm中獲取安全數(shù)據(jù)(如用戶、角色、權(quán)限),即認(rèn)證和授權(quán)等操作所需要的安全數(shù)據(jù)都需要從Realm中獲得;

2.Shiro的核心架構(gòu)

  • Subject:任何直接與應(yīng)用代碼交互的對象;
  • SecurityManager(安全管理器):所有與安全相關(guān)的操作都會與SecurityManager進(jìn)行交互;它管理著所有的Subject;它是Shiro的核心,負(fù)責(zé)與Shiro的其他組件進(jìn)行交互,相當(dāng)于SpringMVC中DispatcherServlet的角色;
  • Authenticator:負(fù)責(zé)Subject認(rèn)證,當(dāng)一個用戶嘗試登錄時,該邏輯被 Authenticator執(zhí)行;且它是一個擴(kuò)展點(diǎn),可以自定義實(shí)現(xiàn);可以使用認(rèn)證策略(Authentication Strategy),即什么情況下算用戶認(rèn)證通過;
  • Authorizer(授權(quán)器):即訪問控制器,用來決定主體(Subject)是否有權(quán)限進(jìn)行相應(yīng)的操作;即控制著用戶能訪問應(yīng)用中的哪些功能;
  • Realm:可以有1個或多個Realm,可以認(rèn)為是安全實(shí)體數(shù)據(jù)源,即用于獲取安全數(shù)據(jù);可以是JDBC實(shí)現(xiàn),也可以是內(nèi)存實(shí)現(xiàn)等等;它由用戶提供,所以一般在應(yīng)用中都需要實(shí)現(xiàn)自己的Realm;
  • SessionManager:管理所有用戶登錄后的會話信息。用戶登錄后用Subject.getSession() 即可獲取會話,在沒有退出之前,用戶的所有信息都在會話中;會話可以是普通JavaSE環(huán)境,也可以是Web環(huán)境的;
  • CacheManager(緩存控制器):管理如用戶、角色、權(quán)限等信息的緩存;因?yàn)檫@些數(shù)據(jù)
    基本上很少改變,放到緩存中后可以提高訪問的性能;
  • Cryptography:密碼模塊,Shiro提供了一些常見的加密組件用于如密碼加密/解密;

四、Shiro入門案例

以下是Shiro官網(wǎng)的一個入門小案例,供我們參考學(xué)習(xí),我們主要關(guān)注其中的Quickstart.class以及shiro.ini中的部分代碼就好。shiro.ini中主要放的就是用戶、角色以及權(quán)限等數(shù)據(jù),Quickstart.class就是簡單的模擬一下認(rèn)證及授權(quán)的過程,其中所用到的數(shù)據(jù)就來源于shiro.ini中,實(shí)際開發(fā)中我們的這些數(shù)據(jù)肯定是從數(shù)據(jù)庫中獲得。

1.shiro.ini

[users] # user 'root' with password 'secret' and the 'admin' role root = secret, admin # user 'guest' with the password 'guest' and the 'guest' role guest = guest, guest # user 'presidentskroob' with password '12345' ("That's the same combination on # my luggage!!!" ;)), and role 'president' presidentskroob = 12345, president # user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz' darkhelmet = ludicrousspeed, darklord, schwartz # user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz' lonestarr = vespa, goodguy, schwartz[roles] # 'admin' role has all permissions, indicated by the wildcard '*' admin = * # The 'schwartz' role can do anything (*) with any lightsaber: schwartz = lightsaber:* # The 'goodguy' role is allowed to 'delete' (action) the User(type) with # license plate 'zhangsan' (instance specific id) goodguy = User:delete:zhangsan

2.Quickstart.class

package com.m33.shiro.helloworld;import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.slf4j.Logger; import org.slf4j.LoggerFactory;public class Quickstart {private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);public static void main(String[] args) {// 創(chuàng)建SecurityManager(下面這三行看看就好)Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);// get the currently executing user// 獲取當(dāng)前的 Subject!調(diào)用 SecurityUtils.getSubject();Subject currentUser = SecurityUtils.getSubject();// Do some stuff with a Session (no need for a web or EJB container!!!)// 測試使用 Session // 首先獲取 Session: Subject的getSession()Session session = currentUser.getSession();session.setAttribute("someKey", "aValue");String value = (String) session.getAttribute("someKey");if (value.equals("aValue")) {log.info("----> Retrieved the correct value! [" + value + "]");}// let's login the current user so we can check against roles and permissions:// 測試當(dāng)前的用戶是否已經(jīng)被認(rèn)證. 即是否已經(jīng)登錄. // 調(diào)用 Subject 的 isAuthenticated() ,若未認(rèn)證,執(zhí)行if里面的代碼if (!currentUser.isAuthenticated()) {// 把用戶名和密碼封裝為 UsernamePasswordToken 對象UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");// remembermetoken.setRememberMe(true);try {// 執(zhí)行登錄. currentUser.login(token);} // 若沒有指定的賬戶, 則 shiro 將會拋出 UnknownAccountException 異常. catch (UnknownAccountException uae) {log.info("----> There is no user with username of " + token.getPrincipal());return; } // 若賬戶存在, 但密碼不匹配, 則 shiro 會拋出 IncorrectCredentialsException 異常。 catch (IncorrectCredentialsException ice) {log.info("----> Password for account " + token.getPrincipal() + " was incorrect!");return; } // 用戶被鎖定的異常 LockedAccountExceptioncatch (LockedAccountException lae) {log.info("The account for username " + token.getPrincipal() + " is locked. " +"Please contact your administrator to unlock it.");}// ... catch more exceptions here (maybe custom ones specific to your application?// 所有認(rèn)證時異常的父類. catch (AuthenticationException ae) {//unexpected condition? error?}}// 成功登錄log.info("----> User [" + currentUser.getPrincipal() + "] logged in successfully.");//test a role:// 測試是否有某一個角色. 調(diào)用 Subject 的 hasRole 方法. if (currentUser.hasRole("schwartz")) {log.info("----> May the Schwartz be with you!");} else {log.info("----> Hello, mere mortal.");return; }//test a typed permission (not instance-level)// 測試用戶是否具備某一個行為. 調(diào)用 Subject 的 isPermitted() 方法。 if (currentUser.isPermitted("lightsaber:weild")) {log.info("----> You may use a lightsaber ring. Use it wisely.");} else {log.info("Sorry, lightsaber rings are for schwartz masters only.");}//a (very powerful) Instance Level permission:// 測試用戶是否具備某一個行為. User:delete:zhangsan: 表示允許刪除User類型的zhangsanif (currentUser.isPermitted("User:delete:zhangsan")) {log.info("----> You are permitted to 'delete'(action) the User(type)with license plate (id) 'zhangsan'. " +"Here are the keys - have fun!");} else {log.info("Sorry, you aren't allowed to 'delete' the 'zhangsan' User!");}//all done - log out!// 執(zhí)行登出. 調(diào)用 Subject 的 Logout() 方法. System.out.println("---->" + currentUser.isAuthenticated()); // truecurrentUser.logout();System.out.println("---->" + currentUser.isAuthenticated()); // falseSystem.exit(0);} }

五、Shiro實(shí)戰(zhàn)-整合進(jìn)Spring Boot

這里先簡單介紹一下我們這次實(shí)戰(zhàn)所要完成的功能,其實(shí)主要就是對用戶登錄進(jìn)行認(rèn)證以及授予某些權(quán)限,讓不同用戶登錄的時候看到不同資源。下面代入實(shí)際的應(yīng)用場景給大家講解一下:
首先我們有三個用戶admin、manager、worker,它們分別具有role(角色):admin、manager、worker;admin角色擁有訪問mobile、salary資源的權(quán)限,manager角色擁有訪問salary資源的權(quán)限;woker角色不具備任何權(quán)限;當(dāng)我們用admin用戶登錄的時候就可以查看mobile和salary,manager只能查看salary,worker則什么都查看不了

1.創(chuàng)建父工程shiroDemo

以下為父工程的pom.xml文件內(nèi)容,需要引入以下依賴

<properties><java.version>1.8</java.version> </properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.3.3.RELEASE</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.6.0</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies> </dependencyManagement>

2.創(chuàng)建shiroAuth子模塊(Maven)

以下為子工程的pom.xml文件內(nèi)容,需要引入以下依賴,具體版本由父工程管理,這里只需添加我們需要用到的依賴即可

<dependencies><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId></dependency> </dependencies>

3.代碼結(jié)構(gòu)講解

下圖是我們本次實(shí)戰(zhàn)項(xiàng)目的代碼結(jié)構(gòu),其中藍(lán)色劃掉的部分先暫時不用管它,后續(xù)我會講解的
下面帶大家先簡單的了解下這些類所要實(shí)現(xiàn)的功能,后面再進(jìn)行更詳細(xì)的講解

類名功能
User實(shí)體類,主要就是定義一些屬性:用戶名、密碼、角色和權(quán)限等
MyRealm一個自定義的Realm,主要負(fù)責(zé)獲取認(rèn)證和授權(quán)所需要的信息
ShiroConfigshiro的配置類,緩存、過濾器等功能在這里進(jìn)行配置,在編譯的時候便會先執(zhí)行該配置類,后續(xù)登錄認(rèn)證或者授權(quán)的時候就會進(jìn)到MyRealm中獲取數(shù)據(jù)
LoginController負(fù)責(zé)登錄業(yè)務(wù)流程的控制
MobileController負(fù)責(zé)獲取mobile
SalaryController負(fù)責(zé)獲取salary
UserService負(fù)責(zé)獲取TestData中數(shù)據(jù),返回給LoginController
MyPassWordEncoder這是我們封裝的對密碼加鹽加密的工具類
TestData一些測試數(shù)據(jù),主要是為了模擬UserService獲取數(shù)據(jù)庫中的數(shù)據(jù),我們這次實(shí)戰(zhàn)并沒有連接數(shù)據(jù)庫,為了測試使用才有了這個工具類,實(shí)際開發(fā)中這些數(shù)據(jù)需要存放在數(shù)據(jù)庫中

4.各個類詳細(xì)講解

User

import java.util.List; public class User {private String userName;private String userPass;private List<String> userRoles; //用戶的角色private List<String> userPerms; //用戶所具有的權(quán)限// 省略構(gòu)造方法和get/set方法... }

MyRealm

import com.m33.shiroAuth.bean.User; import com.m33.shiroAuth.service.UserService; import com.m33.shiroAuth.utils.MyPassWordEncoder; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; 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.subject.Subject; import org.apache.shiro.util.ByteSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;@Configuration(value = "myRealm") public class MyRealm extends AuthorizingRealm {private final Logger logger = LoggerFactory.getLogger(MyRealm.class);@Resourceprivate UserService userService;//授權(quán)@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {logger.info("---------->entered method doGetAuthorizationInfo;");//拿到當(dāng)前用戶Subject subject = SecurityUtils.getSubject();User currentUser = (User)subject.getPrincipal();//寫入當(dāng)前用戶的角色和權(quán)限信息SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();info.addRoles(currentUser.getUserRoles());info.addStringPermissions(currentUser.getUserPerms());return info;}// 認(rèn)證@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {logger.info("--------------->entered method doGetAuthenticationInfo;");//獲得當(dāng)前用戶的tokenUsernamePasswordToken userToken = (UsernamePasswordToken)authenticationToken;//從token中獲得當(dāng)前用戶的用戶名String username = userToken.getUsername();//模擬通過用戶名獲取數(shù)據(jù)庫中用戶密碼User user = userService.getUserByUserName(username);if(null == user){//后續(xù)會拋出UnknownAccountExceptionreturn null;}else{//MyPassWordEncoder.getEncodedPassword()是通過我們的工具類對用戶密碼進(jìn)行加鹽加密//正常是不需要這一步的,注冊的時候就需要對密碼進(jìn)行加鹽加密。因?yàn)槲覀儧]有模擬注冊流程,// 所以現(xiàn)在密碼是明文,我們才需要先把明文密碼加鹽加密,后續(xù)才能與輸入的密碼進(jìn)行比對user.setUserPass(MyPassWordEncoder.getEncodedPassword(user.getUserPass()));//各參數(shù)含義分別為當(dāng)前用戶、用戶密碼(加密后的)、鹽值(里面的“salt”可隨意設(shè)置)、realm名SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getUserPass(),ByteSource.Util.bytes("salt"), "myRealm");//密碼驗(yàn)證邏輯由shiro完成,我們只需返回SimpleAuthenticationInfo對象即可。密碼不匹配會拋出密碼不匹配異常。//密碼正確,會把user對象傳入SecurityUtils.getSubject()。這些都是shiro幫我們做的。return authenticationInfo;}} }

ShiroConfig

import org.apache.shiro.authc.credential.CredentialsMatcher; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.cache.MemoryConstrainedCacheManager; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map;@Configuration public class ShiroConfig {// 1、注冊Realm對象,在MyRealm中有@Configuration(value = "myRealm"),已經(jīng)注冊好Realm對象了//所以以下代碼就不需要了,但是我們需要知道配置shiro一般都需要以下三個步驟,我們可以當(dāng)成模板來記憶,根據(jù)實(shí)際需求進(jìn)行修改即可//@Bean//public Realm myRealm(){// return new MyRealm();// }// 2、DefaultWebSecurityManager @Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("myRealm") AuthorizingRealm myRealm){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 通過HashedCredentialsMatcher 指定算法和加密次數(shù)HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();matcher.setHashAlgorithmName("MD5");matcher.setHashIterations(2);myRealm.setCredentialsMatcher(matcher);//設(shè)置緩存,使用緩存可以避免需要授權(quán)信息時頻繁的調(diào)用數(shù)據(jù)庫查詢的問題。//原理很簡單,只要在SecurityManager里注入CacheManager即可。//我們也可以自定義CacheManager的實(shí)現(xiàn),可以是ehcache、redis等等。//實(shí)際開發(fā)中自定義RedisCache是很常見的,這里由于本人水平有限,就不演示如何用redis實(shí)現(xiàn)緩存了securityManager.setCacheManager(new MemoryConstrainedCacheManager());//最后要把我們的myRealm交給securityManager進(jìn)行管理securityManager.setRealm(myRealm);return securityManager;}//3、ShiroFilterFactoryBean@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();bean.setSecurityManager(securityManager);/*配合Shiro的內(nèi)置過濾器,參見DefaultFilteranon : 無需認(rèn)證就可以訪問authc : 必須認(rèn)證才可以訪問 對應(yīng)@RequiresAuthentication注解user : 用戶登錄且記住我 才可以訪問 對應(yīng)@RequiresUser注解perms : 擁有某個資源才可以訪問 對應(yīng)@RequiresPermissions注解roles : 擁有某個角色才可以訪問 對應(yīng)@RequiresRoles注解*/Map<String, String> filterChainDefinition = new HashMap<>();//配置antMatcher,跟SpringSecurity一樣,可以配**,*,?// **:匹配路徑中的零個或多個路徑,如/admin/**將匹配/admin/a或/admin/a/b// *:匹配零個或多個字符串,如/admin將匹配/admin、/admin123,但不匹配/admin/1// ?:匹配一個字符,如/admin?將匹配/admin1,但不匹配/admin或/admin/filterChainDefinition.put("/mobile/**","perms[mobile]");filterChainDefinition.put("/salary/**","perms[salary]");filterChainDefinition.put("/main.html","authc");//配置登出過濾器filterChainDefinition.put("/logout","logout");//將配好的內(nèi)容添加到攔截器中bean.setFilterChainDefinitionMap(filterChainDefinition);//設(shè)置登錄頁bean.setLoginUrl("/index.html");//設(shè)置成功后跳轉(zhuǎn)的頁面bean.setSuccessUrl("/main.html");//設(shè)置沒有資源權(quán)限時跳轉(zhuǎn)到的頁面bean.setUnauthorizedUrl("/common/noauth");return bean;} }

補(bǔ)充:Shiro中默認(rèn)的過濾器

配置縮寫對應(yīng)的過濾器功能例子
anonAnonymousFilter指定url可以匿名訪問/admins/**=anon
authcFormAuthenticationFilter指定url需要form表單登錄,默認(rèn)會從請求中獲取username、password,rememberMe等參數(shù)并嘗試登錄,如果登錄不了就會跳轉(zhuǎn)到loginUrl配置的路徑。我們也可以用這個過濾器做默認(rèn)的登錄邏輯,但是一般都是我們自己在控制器寫登錄邏輯的,自己寫的話出錯返回的信息都可以定制嘛。/user/**=authc
authcBasicBasicHttpAuthenticationFilter指定url需要basic登錄/user/**=authcBasic
logoutLogoutFilter登出過濾器,配置指定url就可以實(shí)現(xiàn)退出功能,非常方便filterChainDefinition.put(“/logout”,“l(fā)ogout”);
noSessionCreationNoSessionCreationFilter禁止創(chuàng)建會話
permsPermissionsAuthorizationFilter需要指定權(quán)限才能訪問/admin/**=perms[user:add:*],多個perms需要在[]中加“”,中間用,隔開
portPortFilter需要指定端口才能訪問/admins/**=port[8080]
restHttpMethodPermissionFilter將http請求方法轉(zhuǎn)化成相應(yīng)的動詞來構(gòu)造一個權(quán)限字符串,這個感覺意義不大,有興趣自己看源碼的注釋/admin/user/**=perms[user.method],其中method為post,get,delete等
rolesRolesAuthorizationFilter需要指定角色才能訪問/admins/**=roles[“admin,user”]
sslSslFilter需要https請求才能訪問
userUserFilter需要已登錄或“記住我”的用戶才能訪問

LoginController、MobileController、SalaryController

import com.m33.shiroAuth.service.UserService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map;@RequestMapping("/common") @RestController public class LoginController {private final Logger logger = LoggerFactory.getLogger(LoginController.class);@PostMapping("/login")public Object login(String username,String password){Map<String,String> errorCode = new HashMap<>();UsernamePasswordToken token = new UsernamePasswordToken(username,password);Subject user = SecurityUtils.getSubject();//如果用戶已認(rèn)證,直接打印already loginif(user.isAuthenticated()){return "already login";}else{try{//用戶未認(rèn)證,下面進(jìn)行認(rèn)證user.login(token);user.getSession().setAttribute("currentUser",user.getPrincipal());return "login succeed";} catch (UnknownAccountException uae) {//捕獲認(rèn)證過程中出現(xiàn)的各種異常logger.info("There is no user with username of " + token.getPrincipal());errorCode.put("errorMsg","不存在的用戶名");} catch (IncorrectCredentialsException ice) {logger.info("Password for account " + token.getPrincipal() + " was incorrect!");errorCode.put("errorMsg","密碼不正確");} catch (LockedAccountException lae) {logger.info("The account for username " + token.getPrincipal() + " is locked. " +"Please contact your administrator to unlock it.");errorCode.put("errorMsg","賬號被鎖定");} catch(AuthenticationException authe){logger.info("Authentication error ",authe);errorCode.put("errorMsg",authe.getMessage());}return errorCode;}}//獲取當(dāng)前用戶,用于前臺頁面展示用@RequestMapping("/getCurrentUser")public Object getCurrentUser(){Subject subject = SecurityUtils.getSubject();return subject.getSession().getAttribute("currentUser");}//未授權(quán)時執(zhí)行的方法@RequestMapping("/noauth")public String noAuth(){return "未經(jīng)授權(quán),無法訪問。";} } -------------------------------------------------------------- import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/mobile") public class MobileController {/*** 代表一個查手機(jī)號的后臺接口。* @return*/@GetMapping("/query")public String query(){return "mobile";} } ------------------------------------------------------------- import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/salary") public class SalaryController {/*** 代表一個查薪水的后臺接口。* @return*/@RequiresPermissions("salary")@GetMapping("/query")public String query(){return "salary";} }

UserService

import com.m33.shiroAuth.bean.User; import com.m33.shiroAuth.utils.TestData; import org.apache.commons.beanutils.BeanUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; import java.util.stream.Collectors;@Service public class UserService {@Resourceprivate TestData testData;//這里的內(nèi)容看看就好,主要是為了模擬獲取數(shù)據(jù)庫中的用戶數(shù)據(jù),實(shí)際開發(fā)中肯定是直接從數(shù)據(jù)庫中獲得public User getUserByUserName(String username){List<User> queryUsers = testData.getAllUser().stream().filter(user -> username.equals(user.getUserName())).collect(Collectors.toList());if(null != queryUsers && queryUsers.size()>0){try {return (User)BeanUtils.cloneBean(queryUsers.get(0));} catch (Exception e) {e.printStackTrace();return null;}}else{return null;}} }

TestData

import com.m33.shiroAuth.bean.User; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Arrays; import java.util.List;@Component public class TestData {private List<User> allUser;/*** 模擬數(shù)據(jù)庫獲取到的數(shù)據(jù)。* admin用戶 擁有admin角色,擁有mobile和salary兩個資源。* mobile用戶,擁有mobile角色,擁有mobile資源。* worker用戶,擁有worker角色,沒有資源。* @return*/public List<User> getAllUser(){if(null == allUser){allUser = new ArrayList<User>();allUser.add(new User("admin","admin",Arrays.asList("admin"),Arrays.asList("mobile","salary")));allUser.add(new User("manager","manager",Arrays.asList("manager"),Arrays.asList("salary")));allUser.add(new User("worker","worker",Arrays.asList("worker"),Arrays.asList("worker")));}return allUser;} }

MyPassWordEncoder

import org.apache.shiro.crypto.hash.SimpleHash; import org.apache.shiro.util.ByteSource; /*** 負(fù)責(zé)密碼加鹽加密*/ public class MyPassWordEncoder {public static String getEncodedPassword(String password){//各參數(shù)含義分別為加密方式、密碼、鹽值(可隨意設(shè)置)、迭代次數(shù)(指反復(fù)加鹽加密的次數(shù))SimpleHash simpleHash = new SimpleHash("MD5",password, ByteSource.Util.bytes("salt"),2);return simpleHash.toString();} }

以上便是全部類的代碼講解,前端代碼這里就不去研究了,下面補(bǔ)充一下認(rèn)證流程和授權(quán)流程

認(rèn)證流程如下:

  • 1、首先調(diào)用Subject.login(token)進(jìn)行登錄,其會自動委托給SecurityManager
  • 2、SecurityManager負(fù)責(zé)真正的身份驗(yàn)證邏輯;它會委托給Authenticator進(jìn)行身份驗(yàn)證;
  • 3、Authenticator才是真正的身份驗(yàn)證者,ShiroAPI中核心的身份認(rèn)證入口點(diǎn),此處可以自定義插入自己的實(shí)現(xiàn);
  • 4、Authenticator可能會委托給相應(yīng)的AuthenticationStrategy進(jìn)行多Realm身份驗(yàn)證,默認(rèn)ModularRealmAuthenticator會調(diào)用AuthenticationStrategy進(jìn)行多Realm身份驗(yàn)證;
  • 5、Authenticator會把相應(yīng)的token傳入Realm,從Realm獲取身份驗(yàn)證信息,如果沒有返回/拋出異常表示身份驗(yàn)證失敗了。此處可以配置多個Realm,將按照相應(yīng)的順序及策略進(jìn)行訪問。

授權(quán)流程如下:

  • 1、首先調(diào)用Subject.isPermitted*/hasRole*接口,其會委托給SecurityManager,而SecurityManager接著會委托給Authorizer;
  • 2、Authorizer是真正的授權(quán)者,如果調(diào)用如isPermitted(“user:view”),其首先會通過PermissionResolver把字符串轉(zhuǎn)換成相應(yīng)的Permission實(shí)例;
  • 3、在進(jìn)行授權(quán)之前,其會調(diào)用相應(yīng)的Realm獲取Subject相應(yīng)的角色/權(quán)限用于匹配傳入的角色/權(quán)限;
  • 4、Authorizer會判斷Realm的角色/權(quán)限是否和傳入的匹配,如果有多個Realm,會委托給ModularRealmAuthorizer進(jìn)行循環(huán)判斷,如果匹配如isPermitted*/hasRole*會返回true,否則返回false表示授權(quán)失敗。

5.補(bǔ)充多Realm認(rèn)證

當(dāng)我們需要通過Shiro實(shí)現(xiàn)“用戶名/手機(jī)號/郵箱”任意一個都可以登錄的時候,我們就需要用到多Realm認(rèn)證;我們要實(shí)現(xiàn)的效果就是通過用戶名+密碼或者手機(jī)號碼+密碼都可以實(shí)現(xiàn)登錄

修改User類,加一個mobile參數(shù),為了可以通過手機(jī)號登錄

import java.util.List;public class User {private String userName;private String userPass;private String mobile;//補(bǔ)充mobile屬性private List<String> userRoles;private List<String> userPerms;...... }

修改TestData,添加手機(jī)號

public List<User> getAllUser(){if(null == allUser){allUser = new ArrayList<User>();allUser.add(new User("admin","admin","15777777777",Arrays.asList("admin"),Arrays.asList("mobile","salary")));allUser.add(new User("manager","manager","15888888888",Arrays.asList("manager"),Arrays.asList("salary")));allUser.add(new User("worker","worker","15999999999",Arrays.asList("worker"),Arrays.asList("worker")));}return allUser;}

修改UserService類,添加getUserByMobile方法

public User getUserByMobile(String mobile){List<User> queryUsers = testData.getAllUser().stream().filter(user -> mobile.equals(user.getMobile())).collect(Collectors.toList());if(null != queryUsers && queryUsers.size()>0){return queryUsers.get(0);}else{return null;}}

在config下添加MobileRealm,這就是上面那個代碼結(jié)構(gòu)圖劃掉的藍(lán)色部分

import com.m33.shiroAuth.bean.User; import com.m33.shiroAuth.service.UserService; import com.m33.shiroAuth.utils.MyPassWordEncoder; import org.apache.shiro.authc.*; import org.apache.shiro.realm.AuthenticatingRealm; import org.apache.shiro.util.ByteSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; //與MyRealm差不多,但是只需要認(rèn)證流程即可,因?yàn)槲覀冎皇菫榱擞檬謾C(jī)號登錄認(rèn)證 @Configuration(value = "mobileRealm") public class MobileRealm extends AuthenticatingRealm {private final Logger logger = LoggerFactory.getLogger(MobileRealm.class);@Resourceprivate UserService userService;//認(rèn)證@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {logger.info("---->entered method doGetAuthenticationInfo;");UsernamePasswordToken usertoken = (UsernamePasswordToken)authenticationToken;String username = usertoken.getUsername();//只需要管用戶名查詢邏輯。模擬獲取數(shù)據(jù)庫中用戶手機(jī)號User user = userService.getUserByMobile(username);if(null == user){return null; //后續(xù)會拋出UnknownAccountException}else{user.setUserPass(MyPassWordEncoder.getEncodedPassword(user.getUserPass()));SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getUserPass(),ByteSource.Util.bytes("salt"), "mobileRealm");return authenticationInfo;}} }

最后,修改ShiroConfig的getDefaultWebSecurityManager方法

@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("myRealm") AuthorizingRealm myRealm, @Qualifier("mobileRealm") Realm mobileRealm){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();matcher.setHashAlgorithmName("MD5");matcher.setHashIterations(2);myRealm.setCredentialsMatcher(matcher);securityManager.setCacheManager(new MemoryConstrainedCacheManager());//創(chuàng)建多Realm認(rèn)證器,設(shè)置認(rèn)證策略,下面有對認(rèn)證策略進(jìn)行一個簡單的介紹ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());securityManager.setAuthenticator(authenticator);//securityManager.setRealm(myRealm);securityManager.setRealms(Arrays.asList(myRealm,mobileRealm));return securityManager;}

補(bǔ)充:認(rèn)證策略說明,Shiro提供了3個具體的 AuthenticationStrategy 實(shí)現(xiàn)
[1] AtLeastOneSuccessfulStrategy(默認(rèn)實(shí)現(xiàn)):如果一個(或更多)驗(yàn)證成功,則整體的嘗試被認(rèn)為是成功的。如果沒有一個驗(yàn)證成功,則整體失敗。說白了就是,至少有一個Realm的驗(yàn)證是成功的算才認(rèn)證通過,否則認(rèn)證失敗。
[2] FirstSuccessfulStrategy:第一個Realm成功驗(yàn)證返回的信息將被使用,其他的Realm將被忽略。如果沒有一個Realm驗(yàn)證成功,則整體失敗。
[3] AllSuccessfulStrategy:所有配置的Realm都必須驗(yàn)證成功才算認(rèn)證通過,否則認(rèn)證失敗。
補(bǔ)充:Realm的繼承關(guān)系

一般繼承AuthorizingRealm(授權(quán))即可;從圖中我們可以看到它繼承了AuthenticatingRealm(即身份驗(yàn)證),而且也間接繼承了CachingRealm(帶有緩存實(shí)現(xiàn))。

總結(jié)

以上是生活随笔為你收集整理的Shiro从入门到实战(整合进SpringBoot)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

色综合久久久久综合体桃花网 | 精品国产黄色片 | 国产在线播放一区二区三区 | 欧美在线99| 中文字幕亚洲精品在线观看 | 国产在线资源 | 午夜美女av| 手机成人在线 | 中文字幕美女免费在线 | 亚洲电影久久 | 最新日韩视频在线观看 | 99r精品视频在线观看 | 91麻豆产精品久久久久久 | 久久99精品国产91久久来源 | free. 性欧美.com | 粉嫩高清一区二区三区 | 精品一区二区三区香蕉蜜桃 | 成人在线视频网 | 久久国内免费视频 | 天天激情综合网 | 天天曰视频 | 插婷婷 | 天天躁天天躁天天躁婷 | 精品久久99| 国产精品视频资源 | 国产精品门事件 | 日韩在线观看视频网站 | 蜜桃视频日本 | av中文在线 | 国产精品av一区二区 | 91手机电视 | 97精品一区二区三区 | 福利视频精品 | 超碰999| 成年人黄色大全 | 久久久国内精品 | 骄小bbw搡bbbb揉bbbb | 六月婷婷网 | 成年人在线电影 | 免费看在线看www777 | 日韩精品在线观看视频 | 日韩免费在线 | 天天综合网国产 | 精品国产一区二区三区av性色 | 亚洲专区免费观看 | 国产69久久久欧美一级 | 国产精品一区二区免费在线观看 | 日韩在观看线 | 国产一级二级av | 日精品在线观看 | 青青射| 日韩黄色av网站 | 亚洲视频久久久 | 欧美另类v| 久久爽久久爽久久av东京爽 | 中文乱幕日产无线码1区 | 国产精品热视频 | 亚洲精品在线免费播放 | 国产精品久久久久久久毛片 | 国产精品自产拍在线观看中文 | 日日日爽爽爽 | 亚洲国产成人精品在线观看 | 97成人资源站| 成人在线电影观看 | 久久成人麻豆午夜电影 | 久久综合精品国产一区二区三区 | 国产专区视频 | av大片免费在线观看 | 在线观看91网站 | 久久免费成人网 | 国产精品毛片一区二区在线看 | 二区视频在线观看 | 超碰97免费在线 | 国产色婷婷 | 久草青青在线观看 | 黄色片免费电影 | 国产精品久久久久久久妇 | 日韩免费在线观看网站 | 久久国产精品成人免费浪潮 | 丁香婷婷射| 五月天久久狠狠 | 亚洲最大的av网站 | 日韩精品一区二区在线观看视频 | 韩日精品在线 | 不卡中文字幕av | 久久小视频 | 中文字幕国产精品一区二区 | 成人免费中文字幕 | 色综合中文字幕 | 美腿丝袜一区二区三区 | 久久综合久久综合久久综合 | 91在线精品播放 | 日韩在线观看视频免费 | 人人澡人人爽 | 激情五月色播五月 | 岛国一区在线 | 99r精品视频在线观看 | 成年人免费观看在线视频 | 精品国产成人 | 日韩a在线观看 | 欧美日韩成人 | 在线看免费| 五月婷婷深开心 | 99久久婷婷国产精品综合 | 91看片麻豆| 国产视频日韩视频欧美视频 | 久久精品人人做人人综合老师 | 欧美日韩在线精品 | 大胆欧美gogo免费视频一二区 | 日韩欧美xxxx| 麻豆成人小视频 | 日韩中字在线 | 成年人在线看视频 | 国产精品久久久久久久久久久久午 | 视频在线一区二区三区 | 麻豆国产视频 | 可以免费观看的av片 | 丝袜美女视频网站 | 天天爽天天做 | 欧美精品黑人性xxxx | 四虎在线免费视频 | 成人黄色免费在线观看 | 午夜视频在线观看网站 | 依人成人综合网 | 久久97精品 | 婷婷丁香激情 | 国产亚洲精品综合一区91 | 久久综合久久综合久久综合 | 国产精品四虎 | 三级av片 | 中文字幕亚洲精品在线观看 | av网在线观看| 国产不卡免费 | 欧美成年性 | 欧美片网站yy | 国产色婷婷 | 色在线视频网 | 日本黄色大片儿 | 日韩黄色免费电影 | 亚洲精品成人av在线 | 国产成人综合图片 | 日韩精品不卡在线 | 欧美日韩中文视频 | 国产精品系列在线观看 | 午夜视频在线观看一区二区 | 久久久色 | 成人国产一区二区 | 一二区av | 欧美91av| 香蕉在线观看 | 视频在线精品 | 亚洲美女精品视频 | 毛片美女网站 | 中文字幕国内精品 | 久久精品中文视频 | 99色免费视频 | 超碰97网站 | 91av观看 | 开心丁香婷婷深爱五月 | 狠狠gao | 欧美a√在线| 久久高清免费视频 | 日韩毛片在线一区二区毛片 | 久久国产精品系列 | 九九免费在线观看 | 玖草影院 | 国产在线不卡精品 | 综合激情av | 日本不卡一区二区三区在线观看 | 久久精品国产精品亚洲 | 久久久久久久久久亚洲精品 | 91色国产在线 | www.亚洲精品在线 | 免费高清在线观看电视网站 | 国产精品爽爽久久久久久蜜臀 | 午夜的福利 | www.日日操.com| www操操 | 97超碰免费在线 | 亚洲精品美女在线观看播放 | 国产一二三区在线观看 | 亚洲欧美国产视频 | 九九九免费视频 | 国产不卡在线观看 | 香蕉视频免费看 | 久久中文字幕导航 | 欧美一区二区精美视频 | 日韩精品欧美专区 | 99在线观看免费视频精品观看 | 中文字幕在线网址 | 青青看片 | 久久久久欠精品国产毛片国产毛生 | 久久精国产| 99国产精品免费网站 | 欧美日韩高清一区二区 国产亚洲免费看 | 国产精品igao视频网入口 | 午夜视频播放 | 成人影视免费 | 天天操夜夜曰 | 女人18精品一区二区三区 | 久久99在线 | 国产99久久精品 | 国产免费视频一区二区裸体 | 日韩精品一区二区三区外面 | 不卡av在线免费观看 | 有码中文字幕在线观看 | 视色网站 | 亚洲精品中文在线资源 | 在线播放亚洲激情 | 中文字幕在线观看1 | 欧美性大胆 | 成人片在线播放 | 2018亚洲男人天堂 | 成人午夜电影网站 | 91色综合| 久久五月天婷婷 | 一区二区三区在线免费观看视频 | 免费在线播放av电影 | 99精品免费久久久久久久久日本 | 日韩av免费一区 | 色偷偷88888欧美精品久久久 | 中文字幕欧美日韩va免费视频 | 日本黄色免费电影网站 | 久久国产综合视频 | 国产午夜三级 | 国产精品美女久久久久久网站 | 中文字幕超清在线免费 | 免费在线播放av电影 | 天天天射 | 国内精品久久久 | 亚洲欧美视频 | 91九色在线播放 | 色婷婷综合久久久久中文字幕1 | 在线观看免费成人 | 国产在线观看h | 视频1区2区 | 日本精品视频在线 | 天天干天天搞天天射 | 亚洲黄色在线免费观看 | 午夜免费在线观看 | 久久福利国产 | 国产精品久久久久久久久久久久午夜 | 国产福利久久 | 日韩欧美在线观看一区二区 | 色欧美日韩 | 狠狠干五月天 | 欧美美女激情18p | 人人爽人人搞 | 欧美天堂视频在线 | 亚洲国产精久久久久久久 | 美州a亚洲一视本频v色道 | 亚洲精品视频观看 | 久草av在线播放 | 亚洲精品777 | 在线黄色免费 | 精品久久久久久久久久久久 | 91成人黄色 | 91亚洲精品在线 | 久久久久久久av麻豆果冻 | 91精品国产高清自在线观看 | 毛片激情永久免费 | 六月丁香激情综合色啪小说 | 国模视频一区二区三区 | 国产精品不卡av | 91视频免费播放 | 免费看特级毛片 | 玖玖视频免费在线 | 免费观看的av | 日本精品在线视频 | 日本论理电影 | 中文字幕中文字幕在线中文字幕三区 | 中文字幕一区在线 | 成人在线播放免费观看 | 青青河边草观看完整版高清 | av成人动漫在线观看 | 天天操天| 国产精品久久久久久久免费大片 | 日韩专区在线 | 亚洲人人爱| 国产精品一区二区久久国产 | 天天干天天想 | 国产视频69 | 美女黄频视频大全 | 日日夜夜骑 | 91免费高清在线观看 | 久久在线视频精品 | 久久久久久久久久国产精品 | 伊人网av | 国产精品美女久久久久久免费 | 亚洲 综合 专区 | 成人黄色国产 | 色视频成人在线观看免 | 婷婷在线色 | 在线电影日韩 | 在线看黄色av | 久草视频在线观 | 国产色一区 | 91精品视频在线 | 国产99久久久国产精品免费二区 | 日韩av免费在线电影 | 婷婷天天色 | 97超碰人人模人人人爽人人爱 | 99视频免费 | 久久区二区 | www.狠狠操| 久章草在线| 色激情五月 | 日韩av手机在线看 | 日韩有码在线播放 | 美女免费黄视频网站 | 又爽又黄又无遮挡网站动态图 | 免费在线观看成人小视频 | 日韩欧美在线观看一区二区三区 | 亚洲国产精品500在线观看 | 国产一级黄大片 | 国产精品久久网站 | 国产黄色播放 | 亚洲精品乱码久久久久 | 国产超碰在线 | 97视频在线观看视频免费视频 | 免费亚洲婷婷 | 亚洲影视资源 | 欧美性色综合网 | 国产破处在线播放 | 亚洲精品自拍视频在线观看 | 国产成人精品亚洲日本在线观看 | 四虎国产精品免费观看视频优播 | 亚洲 综合 国产 精品 | 亚洲v精品| 久久久免费毛片 | 黄av资源 | 国产精品mm | 日韩欧美在线观看一区二区 | 在线不卡a | 亚洲一区二区三区在线看 | 国产精品 日韩 欧美 | 在线观看国产www | 国产一区二区视频在线 | 丁香av在线| 久久免费美女视频 | 欧美最新另类人妖 | 亚洲精品字幕在线观看 | 日韩精品久久一区二区 | 亚洲女人天堂成人av在线 | 深爱激情开心 | 六月丁香六月婷婷 | 国产精品视频全国免费观看 | 激情综合五月婷婷 | 欧美一级片免费观看 | 日韩成人中文字幕 | 99免费在线播放99久久免费 | 99re8这里有精品热视频免费 | 国产69精品久久99不卡的观看体验 | 日韩在线电影一区 | 黄色性av | 亚洲美女免费精品视频在线观看 | 欧美在线99 | 日日爽日日操 | 伊甸园永久入口www 99热 精品在线 | 蜜臀av性久久久久av蜜臀妖精 | 久久99精品国产麻豆宅宅 | 日韩一级片观看 | 欧美成人h版 | 久久久久免费电影 | 亚洲成人家庭影院 | 精品久久久一区二区 | 一区二区三区免费在线播放 | www99久久 | 99人成在线观看视频 | 在线中文字幕电影 | 美女网站在线 | 亚洲乱码国产乱码精品天美传媒 | 午夜色场 | 麻豆视频观看 | 婷婷丁香自拍 | 超碰97成人 | 成人免费xxx在线观看 | 久久国产日韩 | 99久久www免费 | 国产福利资源 | 欧美一级裸体视频 | 成人久久久精品国产乱码一区二区 | 亚洲综合成人在线 | 日韩国产精品毛片 | 久草综合在线 | 国产探花视频在线播放 | 五月婷婷黄色 | 在线亚洲小视频 | 亚洲伦理中文字幕 | 久久精品99视频 | 在线观看片 | 国产福利精品在线观看 | 国产色区 | 久久国产高清 | 久久激情日本aⅴ | 日韩精品在线观看视频 | 日韩免费播放 | 麻豆视频在线观看免费 | 香蕉日日 | 夜夜躁天天躁很躁波 | 亚洲一区二区高潮无套美女 | 九九热精 | 亚洲视频99| 99热这里只有精品在线观看 | 偷拍久久久 | 免费日韩 精品中文字幕视频在线 | 精品久久久久久国产91 | 日韩精品一区二区三区中文字幕 | 日韩在线免费播放 | 亚洲欧美日本一区二区三区 | 婷婷综合五月天 | 免费高清在线观看成人 | 亚洲精品www久久久 www国产精品com | 日日爱影视 | 午夜精品久久久久久中宇69 | 99成人免费视频 | av中文字幕日韩 | 91精品国产91热久久久做人人 | 国产不卡精品视频 | 超碰在线色 | 人人dvd| 胖bbbb搡bbbb擦bbbb | 首页中文字幕 | 狠狠干狠狠操 | 免费观看性生活大片 | 伊人av综合| www.夜夜草 | 国产成人精品av | 国产亚洲情侣一区二区无 | 久久久久久久久久福利 | 婷婷视频在线观看 | 日韩欧美综合 | 91香蕉视频在线下载 | 久久夜色精品国产欧美乱 | 日韩a在线播放 | 中文字幕 在线 一 二 | 免费成人av在线看 | 成人黄色小视频 | 91精品一区二区三区蜜臀 | 伊人狠狠操 | 色窝资源 | 国产91粉嫩白浆在线观看 | 激情久久小说 | 久草www| 国内精品久久久久久久影视简单 | 天天要夜夜操 | 在线观看日韩国产 | 欧美成人亚洲成人 | 五月婷婷激情六月 | 97视频精品 | 久久99视频免费 | 欧美一级免费在线 | 日韩久久影院 | 精品国产1区 | 国产精品毛片一区视频播不卡 | 国产精品你懂的在线观看 | 另类老妇性bbwbbw高清 | 伊人网av| 欧美色操 | 国产69精品久久99不卡的观看体验 | 一级电影免费在线观看 | 夜色.com | 午夜丰满寂寞少妇精品 | 国产色拍 | 中文字幕亚洲精品日韩 | 在线观看免费高清视频大全追剧 | 色婷婷www| 一区二区视频在线播放 | 精品免费国产一区二区三区四区 | 国产精品视频线看 | 久久久久久久久久影院 | av电影免费在线看 | 久久深夜福利免费观看 | 国产一线二线三线在线观看 | 国产精品久久久网站 | 在线免费看黄色 | 国产五月婷 | 在线视频免费观看 | 婷婷网站天天婷婷网站 | 欧美aaaxxxx做受视频 | 亚洲欧美日韩在线看 | 99热播精品 | 日韩中文字幕在线看 | 综合激情av| 青草视频免费观看 | 一区二区三区精品在线 | 久久精品视频99 | 亚洲一区免费在线 | 99热日本 | 月丁香婷婷 | 久久字幕 | 国产a级片免费观看 | www.com在线观看 | av在线影片 | 免费人成在线观看网站 | 久久亚洲专区 | 韩国视频一区二区三区 | 女人18毛片a级毛片一区二区 | 色婷婷色 | 亚洲成人一二三 | 六月婷色| 国产一区欧美日韩 | 日本在线观看一区二区 | 91超级碰| 狠狠色婷婷丁香六月 | 丁香免费视频 | 成人中文字幕+乱码+中文字幕 | 精品在线观看免费 | 毛片久久久 | 91精品国产综合久久婷婷香蕉 | 天堂久久电影网 | 久久久久成人精品 | 九色91在线视频 | 97精品国产97久久久久久免费 | 国产91丝袜在线播放动漫 | 亚洲精品1区2区3区 超碰成人网 | 一区二区三区四区免费视频 | 中文字幕国产精品一区二区 | 国产少妇在线观看 | 国产群p | 免费看片成年人 | 91成人在线视频观看 | 国内99视频| 日韩电影一区二区三区在线观看 | 国产区在线视频 | 久综合网| 欧美一区二视频在线免费观看 | 日韩影视大全 | 中文字幕 国产视频 | 成人午夜性影院 | 九九热在线免费观看 | 亚洲资源片 | 午夜视频99| 中文在线8新资源库 | 国产成在线观看免费视频 | 亚洲婷婷免费 | 免费在线观看一区二区三区 | 国产一区在线视频播放 | 三日本三级少妇三级99 | 国产精品视频线看 | 国产精品理论片在线播放 | 免费看一及片 | 亚洲精品资源 | av在线免费播放 | 国产在线免费观看 | 91高清不卡 | 欧美一区二视频在线免费观看 | 九九热在线视频免费观看 | 最新高清无码专区 | 99色网站| 日韩精品电影在线播放 | aa一级片 | 日韩一区二区在线免费观看 | 一区二区三区在线影院 | 国产视频一区二区在线 | 毛片无卡免费无播放器 | 正在播放 久久 | 国产精品6| 天天操天天射天天操 | 久久精品国产成人精品 | 亚洲天堂自拍视频 | 久久99久久99精品免费看小说 | 韩国一区二区在线观看 | 亚洲综合色婷婷 | 成人国产电影在线观看 | 国产福利电影网址 | 亚洲精品456在线播放乱码 | 国产原创在线 | 少妇高潮冒白浆 | 五月婷婷综合激情 | 精品国产人成亚洲区 | 在线观看av国产 | 成年人在线免费看视频 | 婷婷色婷婷 | 久久久久久久久国产 | 丁香久久久 | 一级黄色av | 精品在线观看一区二区 | 少妇高潮流白浆在线观看 | 亚洲中字幕 | 国产黄色免费电影 | 国产精品午夜av | 狠狠色丁香 | 日韩欧美国产精品 | www.天天射.com | 韩国三级av在线 | 在线91播放 | 日韩av中文在线 | 91亚洲精品在线观看 | 日日操网 | 激情影音先锋 | 欧美日本中文字幕 | av久久久| 中文字幕之中文字幕 | 在线观看中文字幕亚洲 | 色婷婷综合成人av | 一级免费黄色 | 日韩在线观看一区二区三区 | 久久超级碰 | 亚洲激情 欧美激情 | 韩国av免费观看 | 色午夜影院 | 久久成人毛片 | 贫乳av女优大全 | 欧美精品一区在线 | 激情五月在线观看 | 91久久精品日日躁夜夜躁国产 | 色狠狠狠 | 国产99久久九九精品 | 久久久久久久网 | 色在线免费 | 日日夜夜精品网站 | www.xxxx变态.com | 中文字幕专区高清在线观看 | 91亚洲精品久久久蜜桃网站 | 成人小视频在线免费观看 | 香蕉影视在线观看 | 91精品久久久久久久久久久久久 | 亚洲天天在线 | 在线看国产 | av一级黄| 日韩国产欧美视频 | 国产精品国产自产拍高清av | 九九热中文字幕 | 天天色 天天 | 欧美日韩在线视频观看 | 色综合天天综合网国产成人网 | 亚洲国产精品第一区二区 | 色噜噜在线观看 | 久久精品中文字幕少妇 | 欧美日韩精品区 | 国产精品一区免费观看 | 国产精品h在线观看 | 欧美成人理伦片 | 欧美日韩大片在线观看 | 免费av影视 | 日韩有码欧美 | 久久精品第一页 | 一级a毛片高清视频 | 97品白浆高清久久久久久 | 精品亚洲va在线va天堂资源站 | 国产精品 中文字幕 亚洲 欧美 | 激情www | 五月激情视频 | 国产精品自拍av | 欧美精品一级视频 | 日韩在线观看精品 | 9在线观看免费高清完整版在线观看明 | 天天夜夜亚洲 | 免费能看的av | 国产精品美女在线观看 | 黄色软件视频大全免费下载 | 精品国产乱码一区二 | 99精品欧美一区二区三区黑人哦 | 天天综合精品 | 九九九电影免费看 | 国产精品欧美久久久久久 | 黄色毛片在线观看 | www五月| 在线国产视频一区 | 日韩精品极品视频 | 色在线高清 | 成人毛片网 | 黄色一级免费电影 | 日韩精品一区二区三区高清免费 | 韩国一区二区三区在线观看 | 国内精品久久久久影院一蜜桃 | 涩涩伊人 | 一级片视频在线 | 国产精品com| 人人爱在线视频 | 欧美日韩中文另类 | 成人黄大片 | 国产系列 在线观看 | 91福利影院在线观看 | 天天操天天操天天操 | 亚洲一区av | 中文字幕在线观看的网站 | 国产91学生粉嫩喷水 | 福利视频网站 | 中文欧美字幕免费 | 天天草天天摸 | 婷婷电影在线观看 | 久久精品视频国产 | 亚洲一二区视频 | 麻豆免费观看视频 | 国产精品区二区三区日本 | 欧美伦理一区 | 日韩高清不卡一区二区三区 | 99国产免费网址 | 日韩在线视频看看 | 成人国产电影在线观看 | 91麻豆看国产在线紧急地址 | 欧美九九视频 | 日韩视频免费在线 | 99热免费在线| 视频一区久久 | 色综合久久中文字幕综合网 | 国产精品精品国产色婷婷 | 亚洲欧洲久久久 | 天天操夜夜操国产精品 | 天堂在线成人 | 又黄又爽的免费高潮视频 | 亚州日韩中文字幕 | 精品国产免费av | 亚洲精品国产高清 | www.亚洲黄 | 日韩在线免费高清视频 | 在线观看亚洲成人 | 超碰在线91 | 免费网站看v片在线a | 亚洲黄色激情小说 | 日本中文字幕在线视频 | 欧美性天天 | av在线一级| 亚洲免费资源 | 国产精品无av码在线观看 | 日韩精品亚洲专区在线观看 | 最新中文在线视频 | 一区久久久 | 在线播放日韩av | 国产大陆亚洲精品国产 | 亚洲最新视频在线播放 | 激情电影影院 | 久久久99国产精品免费 | 国产一区二区在线免费播放 | 国产成人免费观看 | 日韩av播放在线 | 亚洲精品在线观看免费 | 日本在线视频一区二区三区 | 美女精品网站 | 日韩肉感妇bbwbbwbbw | 久久精品一二三区白丝高潮 | 久久久黄色| 国产精品永久久久久久久www | 日日夜夜狠狠干 | v片在线播放 | 三上悠亚一区二区在线观看 | 日韩在线视频不卡 | 99精品视频免费在线观看 | av网站免费线看精品 | 视频福利在线 | 久久精品久久精品 | 精品久久久久久久久久久久久久久久 | 区一区二区三区中文字幕 | 国产最新在线观看 | 蜜臀一区二区三区精品免费视频 | 蜜臀av性久久久久av蜜臀妖精 | 韩国av免费看 | 色吊丝在线永久观看最新版本 | 日本动漫做毛片一区二区 | 日韩一区二区免费视频 | 亚洲国产一区在线观看 | 黄色小网站在线 | 国产精品免费在线视频 | 亚洲成av人影院 | 成人黄色电影免费观看 | 久久九九精品久久 | 又黄又爽又无遮挡免费的网站 | 日韩精品免费在线观看 | 国产一区在线视频 | 成年人在线观看视频免费 | 久久撸在线视频 | 欧美亚洲xxx | 国产a级精品 | 国产亚洲综合性久久久影院 | 久草影视在线观看 | 国产中文字幕亚洲 | 97碰视频| 九九在线免费视频 | 人人草在线视频 | 国产又粗又长又硬免费视频 | 婷婷丁香在线 | 九月婷婷综合网 | 九九免费在线观看视频 | 久久久精品久久日韩一区综合 | 欧美成人一二区 | 欧美精品成人在线 | 国产精品亚州 | 国产精品伦一区二区三区视频 | 精品国产区 | 午夜av片 | 久草国产在线 | 在线播放你懂 | 免费裸体视频网 | 黄色片软件网站 | 天天射天 | 国产一区二区在线影院 | 黄色一级免费电影 | 蜜桃视频日本 | av在线进入| 久久se视频 | 97人人模人人爽人人少妇 | 亚洲一区二区精品3399 | 久久国产精品免费一区二区三区 | 国产v在线播放 | 国产精品一区二区在线观看 | 视频在线精品 | 男女靠逼app | 97成人在线视频 | 国产高清一级 | 成人av地址| 91豆花在线观看 | 国产精品久久久久久模特 | 国产成人免费 | 正在播放国产一区二区 | 亚洲影视资源 | 99视频在线精品 | 精品在线观看视频 | 欧美一进一出抽搐大尺度视频 | 美女啪啪图片 | 五月天综合婷婷 | 国产精品视频永久免费播放 | 国产精品资源在线 | 色吊丝在线永久观看最新版本 | 成人免费电影 | av电影免费在线播放 | 玖玖精品在线 | 久草在线视频资源 | 国产原创在线 | 色人久久| 日日综合网 | 日韩视频图片 | 国产精品扒开做爽爽的视频 | 日日碰狠狠添天天爽超碰97久久 | 免费视频二区 | 欧美a影视| 欧美黑人性猛交 | 一级黄网| 91在线视频| 九九热免费视频在线观看 | 国产91勾搭技师精品 | 九九国产精品视频 | 色搞搞| 久久久电影网站 | 精品亚洲免费 | 97超级碰碰碰视频在线观看 | 五月天久久婷 | 麻豆视频一区 | 日日夜夜婷婷 | 亚洲精品动漫成人3d无尽在线 | 久久久高清一区二区三区 | www.国产在线 | 欧美性色网站 | 美女黄频在线观看 | 亚洲va欧美va人人爽春色影视 | 久久精品99精品国产香蕉 | 中文一区在线 | 91av在线免费 | 成人黄色资源 | 亚洲成人黄色在线观看 | 中文字幕国产精品 | 九九热免费观看 | 96超碰在线 | av中文字幕在线看 | 国产一级视频在线 | 你操综合 | 欧美不卡视频在线 | 99r在线| 豆豆色资源网xfplay | 亚洲精品人人 | 日本动漫做毛片一区二区 | 四虎www. | 91天堂影院| 国产精品尤物视频 | 我要看黄色一级片 | 成人午夜电影久久影院 | 久草视频在线资源站 | 丁香网五月天 | 日韩在线不卡 | 欧美大片mv免费 | 国产无套精品久久久久久 | 久精品在线 | 天天干天天操天天干 | 国产91学生粉嫩喷水 | 久久99久久99精品免视看婷婷 | 91在线一区 | 久久www免费人成看片高清 | 精品国自产在线观看 | 亚洲成av人影片在线观看 | 91热视频在线观看 | 一级黄色免费网站 | 在线va视频 | 久久久午夜精品福利内容 | 精品国偷自产在线 | 免费在线观看的av网站 | 久久精品香蕉 | 亚洲国产97在线精品一区 | 久久国产精品一国产精品 | 日韩一级电影在线观看 | 久久五月天婷婷 | 涩涩在线 | 天天操天天玩 | 免费色av | 狠狠干夜夜 | 精品视频免费观看 | 欧美国产亚洲精品久久久8v | 激情视频91| 亚在线播放中文视频 | www91在线 | 亚洲精品玖玖玖av在线看 | 人人草网站 | 黄色小网站免费看 | 亚洲欧洲精品一区二区精品久久久 | 色婷婷激情 | 日本h在线播放 | 国产视频网站在线观看 | 久久精品亚洲一区二区三区观看模式 | 国产女人40精品一区毛片视频 | 国产精品久久久久久久久久东京 | 一区 在线观看 | 九九免费在线视频 | av亚洲产国偷v产偷v自拍小说 | 国产一线在线 | 欧美 亚洲 另类 激情 另类 | 麻豆91精品视频 | 人人草在线视频 | 欧美激情第一区 | 亚洲精品资源在线 | 九九热久久免费视频 | 久久综合99| 中文字幕在线免费观看 | 在线观看mv的中文字幕网站 | 亚洲婷婷丁香 | 麻豆成人在线观看 | 四虎影视精品永久在线观看 | 欧美日韩在线观看不卡 | 一本一本久久a久久 | 国产美女永久免费 | 国产婷婷色 | 国产午夜视频在线观看 | 午夜精品久久久久久久久久久久 | 国产精品国产自产拍高清av | 久久婷婷五月综合色丁香 | 婷婷久久网 | 亚洲一二视频 | 日韩av在线一区二区 | 黄色大全免费网站 | 国产精品久久网站 | 色综合夜色一区 | 免费在线国产 | 国产成人综合在线观看 | 午夜久久久影院 | 久久精品日产第一区二区三区乱码 | www在线免费观看 | 中文字幕在线色 | 日日日爽爽爽 | 婷婷丁香激情五月 | 天天舔天天射天天操 | 激情网五月天 | 久久精品高清视频 | 一区二区三区电影大全 | www.色婷婷.com | 三级动图 | 99久久精品国产免费看不卡 | 精品国产一区二区三区久久影院 | 亚洲一级片在线观看 | 婷婷在线免费观看 | 久久午夜电影院 | 99精品黄色片免费大全 | a视频在线| 日本久久久精品视频 | 日韩精品中文字幕在线观看 | 91精品视屏 | 天堂网一区二区三区 | 免费精品 | 欧美 亚洲 另类 激情 另类 | 超碰97人人干 | 久久久久久免费毛片精品 | 亚洲最大的av网站 | 成人av网址大全 | 国产经典三级 | 中文字幕在线观看网站 | 亚洲久在线 | 成人性生交大片免费观看网站 | 在线观看黄色的网站 | 婷婷深爱五月 | 久久久久久网站 | 日本韩国精品在线 | 国产一区二区久久久久 | 国产在线污 | 97夜夜澡人人双人人人喊 | 91爱爱中文字幕 | 视频一区视频二区在线观看 | 免费av影视 | 精品国产精品一区二区夜夜嗨 | 黄色免费大片 | 97免费视频在线播放 | 午夜国产福利在线 | 国产三级精品三级在线观看 | 在线观看精品黄av片免费 | 精品一区二三区 | 在线观看免费视频 | 中文欧美字幕免费 | 中文字幕在线国产精品 | 97视频在线观看成人 | 午夜视频在线观看一区二区三区 | 亚洲五月婷婷 |