<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Springboot 集成 Shiro 和 CAS 實(shí)現(xiàn)單點(diǎn)登錄(客戶端)

          共 13955字,需瀏覽 28分鐘

           ·

          2022-01-10 23:22

          前言

          這里我先要說(shuō)明一下,我們的項(xiàng)目架構(gòu)是Springboot+Shiro+Ehcache+ThymeLeaf+Mybaits,在這個(gè)基礎(chǔ)上,我們?cè)偌尤肓薈AS單點(diǎn)登錄,雖然前面的框架看著很長(zhǎng),但是和單點(diǎn)登錄相關(guān)的核心架構(gòu)其實(shí)就是Springboot和Shiro而已,所以在看這篇文章之前,需要你掌握的知識(shí)有Springboot的基礎(chǔ)框架搭建以及集成Shiro后的一些操作,因?yàn)橹蟮募蒀AS其實(shí)也是在這個(gè)基礎(chǔ)上進(jìn)行的修改。

          引入Shiro-cas包

          需要集成CAS那么肯定要引入CAS相關(guān)的組件包,在POM.xml中引入:

           1
          2<dependency>
          3????<groupId>org.apache.shirogroupId>
          4????<artifactId>shiro-springartifactId>
          5????<version>1.2.6version>
          6dependency>
          7
          8
          9<dependency>
          10????<groupId>org.apache.shirogroupId>
          11????<artifactId>shiro-ehcacheartifactId>
          12????<version>1.2.6version>
          13dependency>
          14
          15<dependency>
          16????<groupId>org.apache.shirogroupId>
          17????<artifactId>shiro-casartifactId>
          18????<version>1.2.6version>
          19dependency>

          前兩個(gè)一個(gè)是Spring和Shiro結(jié)合的shiro-spring包和與ehcache結(jié)合的shiro-ehcache包,這兩個(gè)包應(yīng)該是之前就有的,之所以也把他們寫(xiě)進(jìn)來(lái)是因?yàn)槿绻隒AS的組件包,需要保證這三個(gè)包的版本號(hào)一致,筆者之前引入的前兩個(gè)包的版本號(hào)是1.2.4,結(jié)果單獨(dú)引入1.2.6的shiro-cas包后,一些cas關(guān)鍵的類是找不到的,所以這里盡量保持這三個(gè)引入包的版本號(hào)一致。

          小插曲
          我在升級(jí)1.2.4的shiro-spring和shiro-ehcache這連個(gè)組件包的時(shí)候,是直接修改的1.2.4為1.2.6,但是引入一直報(bào)錯(cuò),嘗試了各種辦法都不行,后來(lái)發(fā)現(xiàn),你需要剪切該引入包的dependency再黏貼到pom中去,不能直接修改版本號(hào),否則會(huì)出現(xiàn)引入不成功的問(wèn)題,這個(gè)問(wèn)題卡了我一下午,坑啊!

          加入單點(diǎn)登錄的配置

          如果你在你的Springboot項(xiàng)目中集成過(guò)shiro框架,應(yīng)該對(duì)兩個(gè)自定義的類不陌生,一個(gè)是myShiroConfig另一個(gè)是myShiroRealm,這兩個(gè)類其實(shí)就是用戶自定義的Shiro的設(shè)置類和登錄驗(yàn)證獲取權(quán)限的管理類,在這里我將不再贅述該類如何使用,直接上集成了CAS的這兩個(gè)類:
          首先是設(shè)置類:

            1import?com.dhcc.pa.domain.SPermission;
          2import?com.dhcc.pa.other.shiro.MyShiroCasRealm;
          3import?com.dhcc.pa.service.SystemService;
          4import?com.dhcc.pa.util.PublicMsg;
          5import?org.apache.shiro.cache.ehcache.EhCacheManager;
          6import?org.apache.shiro.cas.CasFilter;
          7import?org.apache.shiro.cas.CasSubjectFactory;
          8import?org.apache.shiro.spring.LifecycleBeanPostProcessor;
          9import?org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
          10import?org.apache.shiro.spring.web.ShiroFilterFactoryBean;
          11import?org.apache.shiro.web.mgt.DefaultWebSecurityManager;
          12import?org.slf4j.Logger;
          13import?org.slf4j.LoggerFactory;
          14import?org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
          15import?org.springframework.boot.web.servlet.FilterRegistrationBean;
          16import?org.springframework.context.annotation.Bean;
          17import?org.springframework.context.annotation.Configuration;
          18import?org.springframework.util.StringUtils;
          19import?org.springframework.web.filter.DelegatingFilterProxy;
          20
          21import?javax.servlet.Filter;
          22import?java.util.HashMap;
          23import?java.util.LinkedHashMap;
          24import?java.util.List;
          25import?java.util.Map;
          26
          27@Configuration
          28public?class?ShiroConfig?{
          29
          30????private?static?final?Logger?logger?=?LoggerFactory.getLogger(ShiroConfig.class);
          31
          32????//?Cas登錄頁(yè)面地址
          33????public?static?final?String?casLoginUrl?=?PublicMsg.CASServerUrlPrefix?+?"/login";
          34????//?Cas登出頁(yè)面地址
          35????public?static?final?String?casLogoutUrl?=?PublicMsg.CASServerUrlPrefix??+?"/logout";
          36
          37????//?casFilter?UrlPattern
          38????public?static?final?String?casFilterUrlPattern?=?"/";
          39????//?登錄地址
          40????public?static?final?String?loginUrl?=?casLoginUrl?+?"?service="?+?PublicMsg.SHIROServerUrlPrefix?+?casFilterUrlPattern;
          41????//?登出地址(casserver啟用service跳轉(zhuǎn)功能,需在webapps\cas\WEB-INF\cas.properties文件中啟用cas.logout.followServiceRedirects=true)
          42????public?static?final?String?logoutUrl?=?casLogoutUrl+"?service="+loginUrl;
          43
          44????@Bean
          45????public?EhCacheManager?getEhCacheManager()?{
          46????????EhCacheManager?em?=?new?EhCacheManager();
          47????????em.setCacheManagerConfigFile("classpath:config/ehcache-shiro.xml");
          48????????return?em;
          49????}
          50
          51????@Bean(name?=?"myShiroCasRealm")
          52????public?MyShiroCasRealm?myShiroCasRealm(EhCacheManager?cacheManager)?{
          53????????MyShiroCasRealm?realm?=?new?MyShiroCasRealm();
          54????????realm.setCacheManager(cacheManager);
          55????????return?realm;
          56????}
          57
          58????/**
          59?????*?注冊(cè)DelegatingFilterProxy(Shiro)
          60?????*
          61?????*?@param
          62?????*?@return
          65?????*/

          66????@Bean
          67????public?FilterRegistrationBean?filterRegistrationBean()?{
          68????????FilterRegistrationBean?filterRegistration?=?new?FilterRegistrationBean();
          69????????filterRegistration.setFilter(new?DelegatingFilterProxy("shiroFilter"));
          70????????//??該值缺省為false,表示生命周期由SpringApplicationContext管理,設(shè)置為true則表示由ServletContainer管理
          71????????filterRegistration.addInitParameter("targetFilterLifecycle",?"true");
          72????????filterRegistration.setEnabled(true);
          73????????filterRegistration.addUrlPatterns("/*");
          74????????return?filterRegistration;
          75????}
          76
          77????@Bean(name?=?"lifecycleBeanPostProcessor")
          78????public?LifecycleBeanPostProcessor?getLifecycleBeanPostProcessor()?{
          79????????return?new?LifecycleBeanPostProcessor();
          80????}
          81
          82????@Bean
          83????public?DefaultAdvisorAutoProxyCreator?getDefaultAdvisorAutoProxyCreator()?{
          84????????DefaultAdvisorAutoProxyCreator?daap?=?new?DefaultAdvisorAutoProxyCreator();
          85????????daap.setProxyTargetClass(true);
          86????????return?daap;
          87????}
          88
          89????@Bean(name?=?"securityManager")
          90????public?DefaultWebSecurityManager?getDefaultWebSecurityManager(MyShiroCasRealm?myShiroCasRealm)?{
          91????????DefaultWebSecurityManager?dwsm?=?new?DefaultWebSecurityManager();
          92????????dwsm.setRealm(myShiroCasRealm);
          93//??????
          94????????dwsm.setCacheManager(getEhCacheManager());
          95????????//?指定?SubjectFactory
          96????????dwsm.setSubjectFactory(new?CasSubjectFactory());
          97????????return?dwsm;
          98????}
          99
          100????@Bean
          101????public?AuthorizationAttributeSourceAdvisor?getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager?securityManager)?{
          102????????AuthorizationAttributeSourceAdvisor?aasa?=?new?AuthorizationAttributeSourceAdvisor();
          103????????aasa.setSecurityManager(securityManager);
          104????????return?aasa;
          105????}
          106
          107
          108????/**
          109?????*?CAS過(guò)濾器
          110?????*
          111?????*?@return
          114?????*/

          115????@Bean(name?=?"casFilter")
          116????public?CasFilter?getCasFilter()?{
          117????????CasFilter?casFilter?=?new?CasFilter();
          118????????casFilter.setName("casFilter");
          119????????casFilter.setEnabled(true);
          120????????//?登錄失敗后跳轉(zhuǎn)的URL,也就是?Shiro?執(zhí)行?CasRealm?的?doGetAuthenticationInfo?方法向CasServer驗(yàn)證tiket
          121????????casFilter.setFailureUrl(loginUrl);//?我們選擇認(rèn)證失敗后再打開(kāi)登錄頁(yè)面
          122????????return?casFilter;
          123????}
          124
          125????/**
          126?????*?ShiroFilter

          127?????*?注意這里參數(shù)中的?StudentService?和?IScoreDao?只是一個(gè)例子,因?yàn)槲覀冊(cè)谶@里可以用這樣的方式獲取到相關(guān)訪問(wèn)數(shù)據(jù)庫(kù)的對(duì)象,
          128?????*?然后讀取數(shù)據(jù)庫(kù)相關(guān)配置,配置到 shiroFilterFactoryBean 的訪問(wèn)規(guī)則中。實(shí)際項(xiàng)目中,請(qǐng)使用自己的Service來(lái)處理業(yè)務(wù)邏輯。
          129?????*
          130?????*?@param
          131?????*?@param
          132?????*?@param
          133?????*?@return
          136?????*/

          137????@Bean
          138????public?ShiroFilterFactoryBean?shiroFilter(DefaultWebSecurityManager?securityManager,?CasFilter?casFilter,SystemService?sysPermissionInitService)?{
          139????????ShiroFilterFactoryBean?shiroFilterFactoryBean?=?new?ShiroFilterFactoryBean();
          140????????//?必須設(shè)置?SecurityManager
          141????????shiroFilterFactoryBean.setSecurityManager(securityManager);
          142????????//?如果不設(shè)置默認(rèn)會(huì)自動(dòng)尋找Web工程根目錄下的"/login.jsp"頁(yè)面
          143????????shiroFilterFactoryBean.setLoginUrl(loginUrl);
          144????????//?登錄成功后要跳轉(zhuǎn)的連接
          145????????shiroFilterFactoryBean.setSuccessUrl("/templete");
          146????????shiroFilterFactoryBean.setUnauthorizedUrl("/403");
          147
          148????????//?添加casFilter到shiroFilter中
          149????????Map?filters?=?new?HashMap<>();
          150????????filters.put("casFilter",?casFilter);
          151????????shiroFilterFactoryBean.setFilters(filters);
          152????????///////////////////////?下面這些規(guī)則配置最好配置到配置文件中?///////////////////////
          153????????Map?filterChainDefinitionMap?=?new?LinkedHashMap<>();
          154
          155????????filterChainDefinitionMap.put(casFilterUrlPattern,?"casFilter");//?shiro集成cas后,首先添加該規(guī)則
          156
          157????????// authc:該過(guò)濾器下的頁(yè)面必須驗(yàn)證后才能訪問(wèn),它是Shiro內(nèi)置的一個(gè)攔截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter
          158????????// anon:它對(duì)應(yīng)的過(guò)濾器里面是空的,什么都沒(méi)做
          159????????logger.info("##################從數(shù)據(jù)庫(kù)讀取權(quán)限規(guī)則,加載到shiroFilter中##################");
          160????????filterChainDefinitionMap.put("/js/**",?"anon");
          161????????filterChainDefinitionMap.put("/css/**",?"anon");
          162????????filterChainDefinitionMap.put("/bootstrapDatePicker/**",?"anon");
          163????????//阻止登錄成功后下載favicon
          164????????filterChainDefinitionMap.put("/favicon.ico",?"anon");
          165
          166????????//從數(shù)據(jù)庫(kù)獲取
          167????????List?list?=?sysPermissionInitService.menuGetAll();
          168
          169????????for?(SPermission?sysPermissionInit?:?list)?{
          170????????????if(!StringUtils.isEmpty(sysPermissionInit.getUrl())){
          171????????????????filterChainDefinitionMap.put(sysPermissionInit.getUrl(),
          172????????????????????????"perms["+sysPermissionInit.getPermission()+"]");
          173????????????}
          174????????}
          175????????//配置退出過(guò)濾器,其中的具體的退出代碼Shiro已經(jīng)替我們實(shí)現(xiàn)了
          176????????filterChainDefinitionMap.put(logoutUrl,?"logout");
          177????????filterChainDefinitionMap.put("/**",?"authc");
          178????????shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
          179????????return?shiroFilterFactoryBean;
          180????}
          181
          182}


          注釋寫(xiě)的都比較清楚了, 我這里將不再贅述,這里只有一個(gè)知識(shí)點(diǎn)需要強(qiáng)調(diào)一下:

          在這個(gè)設(shè)置類中如果需要從數(shù)據(jù)庫(kù)獲取用戶的權(quán)限列表,一定要將對(duì)應(yīng)的Service寫(xiě)在shiroFilter這個(gè)方法里當(dāng)作一個(gè)參數(shù)來(lái)使用,而不能直接用@AutoWired將該類引入,否則使用時(shí)會(huì)報(bào)該Service空指針的異常,至于原因我也不是很清楚….待查

          之后是登錄驗(yàn)證和權(quán)限獲取類:

           1import?com.dhcc.pa.domain.Role;
          2import?com.dhcc.pa.domain.SUser;
          3import?com.dhcc.pa.other.config.ShiroConfig;
          4import?com.dhcc.pa.service.UserService;
          5import?com.dhcc.pa.util.PublicMsg;
          6import?org.apache.shiro.authz.AuthorizationInfo;
          7import?org.apache.shiro.authz.SimpleAuthorizationInfo;
          8import?org.apache.shiro.cas.CasRealm;
          9import?org.apache.shiro.subject.PrincipalCollection;
          10import?org.slf4j.Logger;
          11import?org.slf4j.LoggerFactory;
          12import?org.springframework.beans.factory.annotation.Autowired;
          13import?org.springframework.util.StringUtils;
          14
          15import?javax.annotation.PostConstruct;
          16import?java.util.List;
          17
          18
          24public?class?MyShiroCasRealm?extends?CasRealm?{
          25
          26????private?static?final?Logger?logger?=?LoggerFactory.getLogger(MyShiroCasRealm.class);
          27
          28????@Autowired
          29????private?UserService?userService;
          30
          31????@PostConstruct
          32????public?void?initProperty(){
          33//??????setDefaultRoles("ROLE_USER");
          34????????setCasServerUrlPrefix(PublicMsg.CASServerUrlPrefix);
          35????????//?客戶端回調(diào)地址
          36????????setCasService(PublicMsg.SHIROServerUrlPrefix?+?ShiroConfig.casFilterUrlPattern);
          37????}
          38
          39????/**
          40?????*?權(quán)限認(rèn)證,為當(dāng)前登錄的Subject授予角色和權(quán)限
          41?????*?@see?:本例中該方法的調(diào)用時(shí)機(jī)為需授權(quán)資源被訪問(wèn)時(shí)
          42?????*?@see?:并且每次訪問(wèn)需授權(quán)資源時(shí)都會(huì)執(zhí)行該方法中的邏輯,這表明本例中默認(rèn)并未啟用AuthorizationCache
          43?????*?@see?:如果連續(xù)訪問(wèn)同一個(gè)URL(比如刷新),該方法不會(huì)被重復(fù)調(diào)用,Shiro有一個(gè)時(shí)間間隔(也就是cache時(shí)間,在ehcache-shiro.xml中配置),超過(guò)這個(gè)時(shí)間間隔再刷新頁(yè)面,該方法會(huì)被執(zhí)行
          44?????*/

          45????@Override
          46????protected?AuthorizationInfo?doGetAuthorizationInfo(PrincipalCollection?principalCollection)?{
          47????????logger.info("##################執(zhí)行Shiro權(quán)限認(rèn)證##################");
          48????????//獲取用戶的輸入的賬號(hào).
          49????????//獲取當(dāng)前登錄輸入的用戶名,等價(jià)于(String)?principalCollection.fromRealm(getName()).iterator().next();
          50????????String?username?=?(String)super.getAvailablePrincipal(principalCollection);
          51????????//到數(shù)據(jù)庫(kù)查是否有此對(duì)象
          52????????List?userList?=?userService.findByUsername(username);
          53????????System.out.println("----->>userInfo="?+?userList.size());
          54????????if?(userList.size()==0)?{
          55????????????return?null;
          56????????}
          57
          58????????//賬號(hào)判斷;
          59????????//凌海天2017?-11-14?修改
          60????????SUser?user=?userList.get(0);
          61????????if(user!=null){
          62????????????//權(quán)限信息對(duì)象info,用來(lái)存放查出的用戶的所有的角色(role)及權(quán)限(permission)
          63????????????SimpleAuthorizationInfo?info=new?SimpleAuthorizationInfo();
          64????????????int?id??=?user.getId().intValue();
          65????????????//凌海天2017?-11-14?修改
          66????????????List?role?=?userService.findByUserid(id);
          67????????????for?(Role?r?:role){
          68????????????????//用戶的角色集合
          69????????????????if(!StringUtils.isEmpty(r.getRole())){
          70????????????????????info.addRole(r.getRole());
          71????????????????}
          72????????????????//用戶的角色對(duì)應(yīng)的所有權(quán)限,如果只使用角色定義訪問(wèn)權(quán)限
          73????????????????if(!StringUtils.isEmpty(r.getPermission())){
          74????????????????????info.addStringPermission(r.getPermission());
          75????????????????}
          76????????????}
          77????????????//?或者按下面這樣添加
          78????????????//添加一個(gè)角色,不是配置意義上的添加,而是證明該用戶擁有admin角色
          79//????????????simpleAuthorInfo.addRole("admin");
          80????????????//添加權(quán)限
          81//????????????simpleAuthorInfo.addStringPermission("admin:manage");
          82//????????????logger.info("已為用戶[mike]賦予了[admin]角色和[admin:manage]權(quán)限");
          83????????????return?info;
          84????????}
          85????????//?返回null的話,就會(huì)導(dǎo)致任何用戶訪問(wèn)被攔截的請(qǐng)求時(shí),都會(huì)自動(dòng)跳轉(zhuǎn)到unauthorizedUrl指定的地址
          86????????return?null;
          87????}
          88}


          這兩個(gè)類中都用到了PublicMsg類,這個(gè)類里主要設(shè)置的是CAS的服務(wù)端路徑和本項(xiàng)目的對(duì)外路徑,其實(shí)就兩個(gè)參數(shù):

          1//CAS服務(wù)器地址
          2public?static?final?String?CASServerUrlPrefix?=?"http://xxx.xx.xx.xxx:9092/cas";
          3//?當(dāng)前工程對(duì)外提供的服務(wù)地址
          4public?static?final?String?SHIROServerUrlPrefix?=?"http://127.0.0.1:9091";

          讀者可以直接放置到設(shè)置類中,我這里單獨(dú)提出來(lái)是因?yàn)槲业捻?xiàng)目專門(mén)有一個(gè)類管理這些參數(shù)而已。

          查看效果

          在啟動(dòng)CAS服務(wù)端的情況下,啟動(dòng)本項(xiàng)目,然后再瀏覽器中輸入:
          http://localhost:9091
          瀏覽器的url路徑會(huì)自動(dòng)轉(zhuǎn)化為:
          http://172.18.18.25:9092/cas/login?service=http://127.0.0.1:9091/
          這是一個(gè)CAS特有的URL路徑,它的界面如下:

          之后在這個(gè)界面登錄正確的用戶名和密碼后,系統(tǒng)會(huì)自動(dòng)跳轉(zhuǎn)到項(xiàng)目的主頁(yè)中去。

          獲取用戶信息

          在你不在服務(wù)端做任何設(shè)置的默認(rèn)情況下,CAS服務(wù)端只會(huì)給客戶端返回一個(gè)用戶名,比如你的服務(wù)端的用戶名是admin,只要你登錄成功,就會(huì)把服務(wù)端的用戶名傳遞給客戶端,客戶端通過(guò):

          1Subject?currentUser?=?SecurityUtils.getSubject();
          2String?username?=?currentUser.getPrincipal().toString();

          這兩行代碼就可以獲取到登錄用戶的用戶名,然后再通過(guò)自己寫(xiě)的通過(guò)用戶名獲取用戶信息的Service就可以獲取到相關(guān)的用戶信息了,這里應(yīng)該不難理解。

          至于獲取用戶的多屬性,就要結(jié)合到之前的服務(wù)端的設(shè)置了,首先你要在服務(wù)端設(shè)置如下參數(shù):

           1#多屬性
          2cas.authn.attributeRepository.jdbc[0].singleRow=true
          3cas.authn.attributeRepository.jdbc[0].order=0
          4cas.authn.attributeRepository.jdbc[0].url=jdbc:mysql://172.18.18.25:3306/pa_db?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
          5cas.authn.attributeRepository.jdbc[0].username=username
          6cas.authn.attributeRepository.jdbc[0].user=root
          7cas.authn.attributeRepository.jdbc[0].password=1234
          8cas.authn.attributeRepository.jdbc[0].sql=select?*?from?s_user?where?{0}
          9cas.authn.attributeRepository.jdbc[0].dialect=org.hibernate.dialect.MySQLDialect
          10cas.authn.attributeRepository.jdbc[0].ddlAuto=none
          11cas.authn.attributeRepository.jdbc[0].driverClass=com.mysql.jdbc.Driver
          12cas.authn.attributeRepository.jdbc[0].leakThreshold=10
          13cas.authn.attributeRepository.jdbc[0].propagationBehaviorName=PROPAGATION_REQUIRED
          14cas.authn.attributeRepository.jdbc[0].batchSize=1
          15cas.authn.attributeRepository.jdbc[0].healthQuery=SELECT?1
          16cas.authn.attributeRepository.jdbc[0].failFast=trueyeshi

          以上代碼就允許用戶返回服務(wù)端的s_user 數(shù)據(jù)庫(kù)表中的所有字段,當(dāng)然你再客戶端的寫(xiě)法也要跟著改變:

          1AttributePrincipal?principal?=?(AttributePrincipal)?request.getUserPrincipal();
          2final?Map?attributes?=?principal.getAttributes();

          后記

          CAS客戶端的配置差不多就是這樣了,注釋寫(xiě)的都比較明白了,需要注意的坑有以下兩點(diǎn):

          1. 設(shè)置類中的Service引入方式

          2. POM.xml中更改組件版本號(hào)一定要剪切黏貼,不要直接修改版本號(hào)

          剩下的大家看著文章一步一步的走出來(lái)應(yīng)該問(wèn)題就不大了,下一篇我們講兩個(gè)小的內(nèi)容:

          1. 修改CAS服務(wù)端的默認(rèn)登錄頁(yè)

          2. 如何登出CAS客戶端


          1source:jasoncool.github.io/2017/12/04/Springboot集成Shiro和Cas實(shí)現(xiàn)單點(diǎn)登錄-客戶端篇


          喜歡,在看

          瀏覽 71
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲天堂视频在线 | 日韩在线中文字幕视频 | 日本嗯黄色网址 | 深爱五月网 | 亚州三级视频 |