<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    cuiyi's blog(崔毅 crazycy)

    記錄點(diǎn)滴 鑒往事之得失 以資于發(fā)展
    數(shù)據(jù)加載中……

    SpringMVC+MyBatis - 5 Security-Shiro-01

    文章摘錄處

    安全認(rèn)證框架-APACHE SHIRO研究心得

    最近因?yàn)轫?xiàng)目需要,研究了一下Apache Shiro安全認(rèn)證框架,把心得記錄下來。(原創(chuàng)by:西風(fēng)吹雨) 

    Apache Shrio是一個(gè)安全認(rèn)證框架,和Spring Security相比,在于他使用了和比較簡(jiǎn)潔易懂的認(rèn)證和授權(quán)方式。其提供的native-session(即把用戶認(rèn)證后的授權(quán)信息保存在其自身提供Session中)機(jī)制,這樣就可以和HttpSession、EJB Session Bean的基于容器的Session脫耦,到到和客戶端應(yīng)用、Flex應(yīng)用、遠(yuǎn)程方法調(diào)用等都可以使用它來配置權(quán)限認(rèn)證。 

    1、sessionMode 
    在普通的WEB項(xiàng)目中,我們可以選擇使用native session或者是HttpSession,通過設(shè)置securityManager的sessionMode參數(shù)為http或native即可。 

    2、realm
    我們可以基于jdbc,ldap,text,activeDirectory,jndi等多種方式來獲取用戶基本信息,角色信息,權(quán)限信息等。只需要在securityManager中指定使用相應(yīng)的realm實(shí)現(xiàn)即可,其在這各方面都提供了對(duì)應(yīng)的缺省實(shí)現(xiàn),比如我們常用的基于數(shù)據(jù)庫(kù)表的形式來配置用戶權(quán)限信息,就可以使用其缺省實(shí)現(xiàn)的jdbcRealm(org.apache.shiro.realm.jdbc.JdbcRealm)。

    當(dāng)然,如果認(rèn)證信息來自于多方面,多個(gè)不同的來源(比如來自兩個(gè)庫(kù)中,或者一個(gè)數(shù)據(jù)庫(kù),一個(gè)是ldap,再配上一個(gè)缺省的基于文本的測(cè)試用等等),我們可以為securityManager指定realms參數(shù),即把這一組安全配置都配置上。各個(gè)具體的realm實(shí)現(xiàn)提供了方法來獲取用戶基本信息、角色、權(quán)限等。 realm的授權(quán)信息可以存放在Cache中,Cache的名稱可以通過設(shè)置其authorizationCacheName參數(shù)指定。 

    3、緩存 
    目前Shrio缺省提供了基于ehCache來緩存用戶認(rèn)證信息和授權(quán)信息的實(shí)現(xiàn)。只需要配置 org.apache.shiro.web.mgt.DefaultWebSecurityManager 這個(gè) cacheManager并設(shè)置給SecurityManager即可。

    如果項(xiàng)目中已經(jīng)存在使用的ehCacheManager配置(org.springframework.cache.ehcache.EhCacheManagerFactoryBean),DefaultWebSecurityManager則可以指定使用現(xiàn)有的ehCacheManager,如果不指定,它將自行使用缺省配置創(chuàng)建一個(gè)。

    同時(shí),也可以設(shè)置cacheManagerConfigFile參數(shù)來指定ehCache的配置文件。 下例中的shiro.authorizationCache是用來存放授權(quán)信息的Cache,我們?cè)谂渲胷ealm(如myRealm或jdbcReaml)時(shí),把a(bǔ)uthorizationCacheName屬性設(shè)置shiro.authorizationCache來對(duì)應(yīng)。 

    ehcache.xml  
    <ehcache>

    <diskStore path="java.io.tmpdir/tuan-oauth"/>



    <defaultCache
    maxElementsInMemory="10000"
    eternal
    ="false"
    timeToIdleSeconds
    ="120"
    timeToLiveSeconds
    ="120"
    overflowToDisk
    ="false"
    diskPersistent
    ="false"
    diskExpiryThreadIntervalSeconds
    ="120"
    />

    <!-- We want eternal="true" (with no timeToIdle or timeToLive settings) because Shiro manages session
    expirations explicitly. If we set it to false and then set corresponding timeToIdle and timeToLive properties,
    ehcache would evict sessions without Shiro's knowledge, which would cause many problems
    (e.g. "My Shiro session timeout is 30 minutes - why isn't a session available after 2 minutes?"
    Answer - ehcache expired it due to the timeToIdle property set to 120 seconds.)

    diskPersistent=true since we want an enterprise session management feature - ability to use sessions after
    even after a JVM restart. 
    -->
    <cache name="shiro-activeSessionCache"
    maxElementsInMemory
    ="10000"
    eternal
    ="true"
    overflowToDisk
    ="true"
    diskPersistent
    ="true"
    diskExpiryThreadIntervalSeconds
    ="600"/>

    <cache name="shiro.authorizationCache"
    maxElementsInMemory
    ="100"
    eternal
    ="false"
    timeToLiveSeconds
    ="600"
    overflowToDisk
    ="false"/>

    </ehcache>

    當(dāng)我們把securityManager的sessionMode參數(shù)設(shè)置為native時(shí),那么shrio就將用戶的基本認(rèn)證信息保存到缺省名稱為shiro-activeSessionCache 的Cache中 

    org.apache.shiro.web.mgt.DefaultWebSecurityManager 在sessionMode參數(shù)設(shè)置為native時(shí),缺省使用的是DefaultWebSessionManager來管理Session,該管理類缺省使用的是使用MemorySessionDAO基于內(nèi)存來保存和操作用戶基本認(rèn)證信息。

    如果系統(tǒng)內(nèi)的用戶數(shù)特別多,我們需要使用CacheSessionDao來基于Cache進(jìn)行操作,因此,這里需要顯示配置一個(gè)sessionManager(org.apache.shiro.web.session.mgt.DefaultWebSessionManager),并配置該sessionManager的sessionDao為CacheSessionDao(org.apache.shiro.session.mgt.eis.CachingSessionDAO,需用其實(shí)現(xiàn)類org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO)。

    配置CacheSessionDao時(shí),我們可以指定屬性activeSessionsCacheName的名稱來替換掉缺省名 shiro-activeSessionCache。我們?cè)侔言搒essionManager配置給DefaultWebSecurityManager就可以了。 

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        
    <property name="cacheManager" ref="cacheManager" />
        
    <property name="sessionMode" value="native" />
        
    <!-- Single realm app. If you have multiple realms, use the 'realms' property 
            instead. 
    -->
        
    <property name="realm" ref="myRealm" />
        
    <property name="sessionManager" ref="sessionManager" />
    </bean>

    <bean id="sessionManager"
        class
    ="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        
    <property name="sessionDAO" ref="sessionDAO" />
    </bean>

    <bean id="sessionDAO"
        class
    ="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
        
    <property name="activeSessionsCacheName" value="shiro-activeSessionCache" />
    </bean>
      
    從以上我們可以看出 
    a、我們可以指定sessionManager的sessionDao,在某些情況下,我們也可以通過實(shí)現(xiàn)自定義的sessionDao來把用戶認(rèn)證信息保存在memcache,mongodb,ldap,database中,達(dá)到和其他應(yīng)用共享用戶認(rèn)證信息的目的,以此達(dá)到SSO的目的(當(dāng)然,sessionId得一致,這個(gè)屬于我們可以在應(yīng)用商定怎么設(shè)定一致的sessionId的問題)。 

    b、cacheManager我們也可以自己實(shí)現(xiàn)一個(gè),可以根據(jù)應(yīng)用情況來考慮,比如存放在memcache中之類。 

    4、配置 
    Web項(xiàng)目中,普通的web項(xiàng)目可以采用ini文件來對(duì)shiro進(jìn)行配置。基于spring的項(xiàng)目可以采用和Spring集成的方式配置。 基于Spring集成的Web項(xiàng)目的基本配置文件如下: 
     
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context
    ="http://www.springframework.org/schema/context"
        xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation
    ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"
    >

        
    <!-- ========================================================= Shiro Core 
            Components - Not Spring Specific ========================================================= 
    -->

        
    <!-- Shiro's main business-tier object for web-enabled applications (use 
            DefaultSecurityManager instead when there is no web environment) 
    -->
        
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            
    <property name="cacheManager" ref="cacheManager" />
            
    <!-- Single realm app. If you have multiple realms, use the 'realms' property 
                instead. 
    -->
            
    <property name="sessionMode" value="native" />
            
    <property name="realm" ref="myRealm" />
        
    </bean>

        
    <!-- Let's use some enterprise caching support for better performance. You 
            can replace this with any enterprise caching framework implementation that 
            you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc 
    -->
        
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
            
    <!-- Set a net.sf.ehcache.CacheManager instance here if you already have 
                one. If not, a new one will be creaed with a default config: 
    -->
            
    <property name="cacheManager" ref="ehCacheManager" />
            
    <!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance 
                to inject, but you want a specific Ehcache configuration to be used, specify 
                that here. If you don't, a default will be used.: <property name="cacheManagerConfigFile" 
                value="classpath:some/path/to/ehcache.xml"/> 
    -->
        
    </bean>

        
    <!-- Used by the SecurityManager to access security data (users, roles, 
            etc). Many other realm implementations can be used too (PropertiesRealm, 
            LdapRealm, etc. 
    -->
        
    <bean id="jdbcRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">
            
    <property name="name" value="jdbcRealm" />
            
    <property name="dataSource" ref="dataSource" />
            
    <property name="credentialsMatcher">
                
    <!-- The 'bootstrapDataPopulator' Sha256 hashes the password (using the 
                    username as the salt) then base64 encodes it: 
    -->
                
    <bean class="org.apache.shiro.authc.credential.Sha256CredentialsMatcher">
                    
    <!-- true means hex encoded, false means base64 encoded -->
                    
    <property name="storedCredentialsHexEncoded" value="false" />
                    
    <!-- We salt the password using the username, the most common practice: -->
                    
    <property name="hashSalted" value="true" />
                
    </bean>
            
    </property>
            
    <property name="authorizationCacheName" value="shiro.authorizationCache" />
        
    </bean>

        
    <bean id="myRealm" class="org.apache.shiro.realm.text.IniRealm"
            init-method
    ="init">
            
    <property name="name" value="myRealm" />
            
    <property name="authorizationCacheName" value="shiro.authorizationCache" />
            
    <property name="resourcePath" value="classpath:config/myRealm.ini" />

        
    </bean>

        
    <!-- ========================================================= Shiro Spring-specific 
            integration ========================================================= 
    -->
        
    <!-- Post processor that automatically invokes init() and destroy() methods 
            for Spring-configured Shiro objects so you don't have to 1) specify an init-method 
            and destroy-method attributes for every bean definition and 2) even know 
            which Shiro objects require these methods to be called. 
    -->
        
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

        
    <!-- Enable Shiro Annotations for Spring-configured beans. Only run after 
            the lifecycleBeanProcessor has run: 
    -->
        
    <bean
            
    class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
            depends-on
    ="lifecycleBeanPostProcessor" />
        
    <bean
            
    class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            
    <property name="securityManager" ref="securityManager" />
        
    </bean>


        
    <!-- Secure Spring remoting: Ensure any Spring Remoting method invocations 
            can be associated with a Subject for security checks. 
    -->
        
    <bean id="secureRemoteInvocationExecutor"
            class
    ="org.apache.shiro.spring.remoting.SecureRemoteInvocationExecutor">
            
    <property name="securityManager" ref="securityManager" />
        
    </bean>

        
    <!-- Define the Shiro Filter here (as a FactoryBean) instead of directly 
            in web.xml - web.xml uses the DelegatingFilterProxy to access this bean. 
            This allows us to wire things with more control as well utilize nice Spring 
            things such as PropertiesPlaceholderConfigurer and abstract beans or anything 
            else we might need: 
    -->
        
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            
    <property name="securityManager" ref="securityManager" />
            
    <property name="loginUrl" value="/login" />
            
    <property name="successUrl" value="/index" />
            
    <property name="unauthorizedUrl" value="/unauthorized" />
            
    <!-- The 'filters' property is not necessary since any declared javax.servlet.Filter 
                bean defined will be automatically acquired and available via its beanName 
                in chain definitions, but you can perform overrides or parent/child consolidated 
                configuration here if you like: 
    -->
            
    <!-- <property name="filters"> <util:map> <entry key="aName" value-ref="someFilterPojo"/> 
                </util:map> </property> 
    -->
            
    <property name="filterChainDefinitions">
                
    <value>
                    /login = authc
                    /account = user
                    /manage = user,roles[admin]
                
    </value>
            
    </property>
        
    </bean>
    </beans>
      
    5、基于url資源的權(quán)限管理 
    我們可以簡(jiǎn)單配置在shiroFilter的filterChainDefinitions中,也可以考慮通過一個(gè)文本文件,我們讀入內(nèi)容后設(shè)置進(jìn)去。或者通過Ini類來裝入Ini文件內(nèi)容,到時(shí)取出urls的部分來設(shè)置給shiroFilter的filterChainDefinitions。也可以把這部分?jǐn)?shù)據(jù)存入數(shù)據(jù)庫(kù)表中,到時(shí)讀出一個(gè)Map來設(shè)置給shiroFilter的filterChainDefinitionsMap屬性。 

    6、url的配置 
    authc是認(rèn)證用戶(rememberMe的用戶也必須再次登錄才能訪問該url),配置成user才能讓rememberMe用戶也可以訪問。 

    7、rememberMe Cookie的處理 
    Shiro有一套缺省機(jī)制,由CookieRememberMeManager實(shí)現(xiàn)。其有一個(gè)SimpleCookie類,保存對(duì)應(yīng)的用戶信息等。

    每次保存時(shí),系統(tǒng)把SimpleCookie的信息設(shè)置好之后,先用DefaultSerializer把其用jvm缺省序列化方式序列化成byte[],然后再用cipherService(缺省是aes加密算法)來加密該byte[],最后用Base64.encodeToString(serialized)壓縮成一個(gè)字符串,再寫入名稱為rememberMe的Cookie中。 

    讀取時(shí),通過把該rememberMe Cookie的內(nèi)容用byte[] decoded = Base64.decode(base64)解壓出該byte[],再用cipherService解密,最后用DefaultSerializer反序列化出來該SimpleCookie類。 

    如果我們有自定義的rememberMe Cookie需要處理,特別是在和其他網(wǎng)站一起SSO,通過訪問主域的Cookie來獲取記錄的用戶信息時(shí),我們需要重新實(shí)現(xiàn)rememberMeManager(可以考慮繼承AbstractRememberMeManager),和根據(jù)實(shí)際用的序列化方式Serializer來實(shí)現(xiàn)一個(gè)(比如考慮通用性,用json方式序列化)。

    在Spring配置中,配置好RememberMeManager,裝配上sericerlizer和cipherService(根據(jù)實(shí)際情況選用適當(dāng)?shù)募用芩惴ǎ詈蟀裷ememberMeManager設(shè)置給DefaultWebSecurityManager即可。如果非常簡(jiǎn)單的cookie,可以直接實(shí)現(xiàn)RememberMeManager的幾個(gè)接口方法也行


    【Apache Shiro in Spring】自定義filterChainDefinitions和Realm
    文章出處

    在Spring Context中定義shiroFilter(org.apache.shiro.spring.web.ShiroFilterFactoryBean)時(shí)需要為其filterChainDefinitions property賦值,這個(gè)屬性是個(gè)chainName-to-chainDefinition map of chain definitions,用于為URL定義過濾策略。

    filterChainDefinitions是一個(gè)set method,他調(diào)用setFilterChainDefinitionMap(section),F(xiàn)ilterChainDefinitionMap是個(gè)Field。

    比如,這是我定義的:

    /404.htm = anon /main!main.html = anon /**.html = perms[myPerm_1]


    在這里引用一下某前輩總結(jié)的chainDefinition,如下:

    rest:比如/admins/user/**=rest[user],根據(jù)請(qǐng)求的方法,相當(dāng)于/admins/user/**=perms[user:method] ,其中method為post,get,delete等。

    port:比如/admins/user/**=port[8081],當(dāng)請(qǐng)求的url的端口不是8081是跳轉(zhuǎn)到schemal://serverName:8081?queryString,其中schmal是協(xié)議http或https等,serverName是你訪問的host,8081是url配置里port的端口,queryString是你訪問的url里的?后面的參數(shù)。

    perms:比如/admins/user/**=perms[user:add:*],perms參數(shù)可以寫多個(gè),多個(gè)時(shí)必須加上引號(hào),并且參數(shù)之間用逗號(hào)分割,比如/admins/user/**=perms["user:add:*,user:modify:*"],當(dāng)有多個(gè)參數(shù)時(shí)必須每個(gè)參數(shù)都通過才通過,想當(dāng)于isPermitedAll()方法。

    roles:比如/admins/user/**=roles[admin],參數(shù)可以寫多個(gè),多個(gè)時(shí)必須加上引號(hào),并且參數(shù)之間用逗號(hào)分割,當(dāng)有多個(gè)參數(shù)時(shí),比如/admins/user/**=roles["admin,guest"],每個(gè)參數(shù)通過才算通過,相當(dāng)于hasAllRoles()方法。

    anon:比如/admins/**=anon 沒有參數(shù),表示可以匿名使用。

    authc:比如/admins/user/**=authc表示需要認(rèn)證才能使用,沒有參數(shù)

    authcBasic:比如/admins/user/**=authcBasic沒有參數(shù)表示httpBasic認(rèn)證

    ssl:比如/admins/user/**=ssl沒有參數(shù),表示安全的url請(qǐng)求,協(xié)議為https

    user:比如/admins/user/**=user沒有參數(shù)表示必須存在用戶,當(dāng)?shù)侨氩僮鲿r(shí)不做檢查


    一般情況下,我們可以將模塊作為一個(gè)授權(quán)單位,例如:

    /blog!**.html = user

    偶爾也會(huì)有將每一個(gè)URL作為一個(gè)授權(quán)單位進(jìn)行控制,例如:

    /blog!doAddNewArticle.html = authc,perms[addArticle]

    但是URL的數(shù)量讓人頭疼,也許可以每開發(fā)一個(gè)功能的時(shí)候打開XML文件寫入U(xiǎn)RL然后同步到SVN,或者我們也可以找一個(gè)人專門做這些事情,無論是添加、刪除功能還是修改方法名都通知這個(gè)人去做...換位思考一下,我不希望我是這個(gè)人...

    所以我要把這些URL放在數(shù)據(jù)庫(kù)進(jìn)行管理。我要把他們統(tǒng)統(tǒng)Query出來放到filterChainDefinitions里。
    我需要裝配一個(gè)Bean,實(shí)際上他是一個(gè)org.springframework.beans.factory.FactoryBean<Section>的實(shí)現(xiàn)。

    <bean id="chainFilterBuff"   class="king.common.ChainFilterBuff">
        <property name="filterChainDefinitions">
        /404.htm = anon
        /main!main.html = anon
        </property>
    </bean>

    然后將其注入:

    <bean id="shiroFilter1" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/main!main.html" />
        <property name="successUrl" value="/main!main.html" />
        <property name="unauthorizedUrl" value="/unAuthorized.htm" />
        <property name="filterChainDefinitionMap" ref="chainFilterBuff" />
    </bean>


    Java代碼中implements FactoryBean<Ini.Section>并實(shí)現(xiàn)需要Override的method,關(guān)鍵是getObject這個(gè)method:

    private String filterChainDefinitions;
    @Override
    public Section getObject() throws Exception {
        Ini ini = new Ini();
        ini.load(filterChainDefinitions);   //先載入XML中定義好的chain
        Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
        /*
         *  省略讀取步驟
         *  繼續(xù)加入數(shù)據(jù)庫(kù)中的chain
         *  section.put("/**", "authc, roles[admin]");
         
    */
                                                                                                                                                                                                                                                                                                                                           
        return section;
    }

    等等,這些僅僅是定義了權(quán)限。

    我們需要在用戶訪問這些URL的時(shí)候去驗(yàn)證一下用戶是否具備當(dāng)前URL權(quán)限。
    所以我定義了(事實(shí)上我們必須定義一個(gè)Realm,ShiroFilterFactoryBean需要SecurityManager,而我們使用的SecurityManager的實(shí)現(xiàn)類DefaultWebSecurityManager則需要一個(gè)Realm!):

    <bean id="shiroDataBaseRealm" class="king.security.KingMainRealm">

    并且Override了接口定義的method:

    public class KingMainRealm extends AuthorizingRealm {
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo( //授權(quán)
                PrincipalCollection principals) {
            UserBean _user = (UserBean) principals.fromRealm(getName()).iterator().next();
            SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo();
                    /*
                     * 省略
                     
    */
            return authInfo;
        }
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo( //認(rèn)證
                AuthenticationToken token) throws AuthenticationException {
            UserBean user = new UserBean();
            UsernamePasswordToken userToken = (UsernamePasswordToken)token;
            user.setUserName(userToken.getUsername());
            user.setPassword(userToken.getPassword());
                                                      
            return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
        }
    }

    若已定義了需要請(qǐng)求的URL,用戶登錄時(shí)doGetAuthorizationInfo會(huì)被調(diào)用,剩下的就是為每一個(gè)用戶管理這些權(quán)限了。

    也許我們可以創(chuàng)建角色關(guān)聯(lián)多個(gè)權(quán)限,用戶關(guān)聯(lián)多個(gè)角色,類似這樣的設(shè)置不同的層次。
    按你喜歡的方式去做吧 

    posted on 2014-07-11 09:38 crazycy 閱讀(2266) 評(píng)論(0)  編輯  收藏 所屬分類: JavaEE技術(shù)

    主站蜘蛛池模板: 亚洲视频在线观看| 亚洲国产精品一区第二页 | 在人线av无码免费高潮喷水| 免费看美女裸露无档网站| 日韩精品无码区免费专区| 国产免费爽爽视频免费可以看| 亚洲一区二区三区免费| 亚洲AV无码乱码在线观看裸奔| 亚洲视频在线观看视频| 亚洲国产成人久久精品大牛影视| 永久免费精品影视网站| 一区二区三区四区免费视频 | 久久精品国产亚洲AV蜜臀色欲| 国产精品久久久久久亚洲影视| 国产免费一区二区三区免费视频| 一区二区三区观看免费中文视频在线播放 | 亚洲AV日韩精品久久久久| 亚洲av无码专区在线| 亚洲国产成人AV网站| 成全动漫视频在线观看免费高清版下载| 亚洲美女视频免费| 四虎永久在线精品免费观看地址 | 成在线人永久免费视频播放| 好看的亚洲黄色经典| 涩涩色中文综合亚洲| 成av免费大片黄在线观看| 好男人www免费高清视频在线| 亚洲综合另类小说色区色噜噜| 亚洲精品综合久久中文字幕| 国产精品亚洲AV三区| 日本卡1卡2卡三卡免费| 免费高清在线影片一区| 国产亚洲成AV人片在线观黄桃| 亚洲高清有码中文字| 两个人看www免费视频| 毛片在线看免费版| 国产成人精品日本亚洲网站| 久久精品国产亚洲AV麻豆网站| 国产成人高清亚洲一区久久| 99re热精品视频国产免费| 嫩草影院免费观看|