国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
shiro spring

apache shiro是一個(gè)安全認(rèn)證框架,和spring security相比,在于他使用了比較簡潔易懂的認(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)證。 在exit-web-framework里的vcs-admin例子用到該框架,具體使用說明可以參考官方幫助文檔。在這里主要講解如何與spring結(jié)合、動(dòng)態(tài)創(chuàng)建filterchaindefinitions、以及認(rèn)證、授權(quán)、和緩存處理。

apache shiro 結(jié)合spring

Shiro 擁有對Spring Web 應(yīng)用程序的一流支持。在Web 應(yīng)用程序中,所有Shiro 可訪問的萬惡不請求必須通過一個(gè)主要的Shiro 過濾器。該過濾器本身是極為強(qiáng)大的,允許臨時(shí)的自定義過濾器鏈基于任何URL 路徑表達(dá)式執(zhí)行。 在Shiro 1.0 之前,你不得不在Spring web 應(yīng)用程序中使用一個(gè)混合的方式,來定義Shiro 過濾器及所有它在web.xml中的配置屬性,但在Spring XML 中定義SecurityManager。這有些令人沮喪,由于你不能把你的配置固定在一個(gè)地方,以及利用更為先進(jìn)的Spring 功能的配置能力,如PropertyPlaceholderConfigurer 或抽象bean 來固定通用配置?,F(xiàn)在在Shiro 1.0 及以后版本中,所有Shiro 配置都是在Spring XML 中完成的,用來提供更為強(qiáng)健的Spring 配置機(jī)制。以下是如何在基于Spring web 應(yīng)用程序中配置Shiro: web.xml:

<!-- Spring ApplicationContext配置文件的路徑,可使用通配符,多個(gè)路徑用,號分隔 此參數(shù)用于后面的Spring Context Loader --><context-param>    <param-name>contextConfigLocation</param-name>    <param-value>        classpath*:/applicationContext-shiro.xml    </param-value></context-param><!-- shiro security filter --><filter>    <!-- 這里的filter-name要和spring的applicationContext-shiro.xml里的            org.apache.shiro.spring.web.ShiroFilterFactoryBean的bean name相同 -->    <filter-name>shiroSecurityFilter</filter-name>    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>    <init-param>        <param-name>targetFilterLifecycle</param-name>        <param-value>true</param-value>    </init-param></filter><filter-mapping>    <filter-name>shiroSecurityFilter</filter-name>    <url-pattern>/*</url-pattern></filter-mapping>

applicationContext-shiro.xml文件中,定義web支持的SecurityManager和"shiroSecurityFilter"bean將會被web.xml 引用。

<bean id="shiroSecurityFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">    <!-- shiro的核心安全接口 -->    <property name="securityManager" ref="securityManager" />    <!-- 要求登錄時(shí)的鏈接 -->    <property name="loginUrl" value="/login.jsp" />    <!-- 登陸成功后要跳轉(zhuǎn)的連接 -->    <property name="successUrl" value="/index.jsp" />    <!-- 未授權(quán)時(shí)要跳轉(zhuǎn)的連接 -->    <property name="unauthorizedUrl" value="/unauthorized.jsp" />    <!-- shiro連接約束配置 -->    <propery name="filterChainDefinitions">        <value>            /login = authc            /logout = logout            /resource/** = anon        </value>    </property></bean><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"></bean><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

啟用Shiro注解

在獨(dú)立應(yīng)用程序和Web應(yīng)用程序中,你可能想為安全檢查使用Shiro 的注釋(例如,@RequiresRoles,@RequiresPermissions 等等)。這需要Shiro 的Spring AOP 集成來掃描合適的注解類以及執(zhí)行必要的安全邏輯。以下是如何使用這些注解的。只需添加這兩個(gè)bean:

<bean class="org.springframwork.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/><bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">    <property name="securityManager" ref="securityManager"/></bean>

動(dòng)態(tài)創(chuàng)建filterchaindefinitions

有時(shí),在某些系統(tǒng)想通過讀取數(shù)據(jù)庫來定義org.apache.shiro.spring.web.ShiroFilterFactoryBean的filterChainDefinitions。這樣能夠通過操作界面或者維護(hù)后臺來管理系統(tǒng)的鏈接。

在shrio與spring集成好了以后,調(diào)試源碼的高人可能已經(jīng)注意到。項(xiàng)目啟動(dòng)時(shí),shrio通過自己的org.apache.shiro.spring.web.ShiroFilterFactoryBean類的filterChainDefinitions(授權(quán)規(guī)則定義)屬性轉(zhuǎn)換為一個(gè)filterChainDefinitionMap,轉(zhuǎn)換完成后交給ShiroFilterFactoryBean保管。ShiroFilterFactoryBean根據(jù)授權(quán)(AuthorizationInfo類)后的信息去判斷哪些鏈接能訪問哪些鏈接不能訪問。filterChainDefinitionMap里面的鍵就是鏈接URL,值就是存在什么條件才能訪問該鏈接,如perms、roles。filterChainDefinitionMap是一個(gè)Map,shiro擴(kuò)展出一個(gè)Map的子類Ini.Section

現(xiàn)在有一張表的描述實(shí)體類,以及數(shù)據(jù)訪問:

@Entity@Table(name="TB_RESOURCE")public class Resource implements Serializable {    //主鍵id    @Id    private String id;    //action url    private String value;    //shiro permission;    private String permission;    //------------------Getter/Setter---------------------//}

@Repositorypublic class ResourceDao extends BasicHibernateDao<Resource, String> {}

通過該類可以知道permission字段和value就是filterChainDefinitionMap的鍵/值,用spring FactoryBean接口的實(shí)現(xiàn)getObject()返回Section給filterChainDefinitionMap即可

public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section>{    @Autowired    private ResourceDao resourceDao;    private String filterChainDefinitions;    /**     * 默認(rèn)premission字符串     */    public static final String PREMISSION_STRING="perms[\"{0}\"]";    public Section getObject() throws BeansException {        //獲取所有Resource        List<Resource> list = resourceDao.getAll();        Ini ini = new Ini();        //加載默認(rèn)的url        ini.load(filterChainDefinitions);        Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);        //循環(huán)Resource的url,逐個(gè)添加到section中。section就是filterChainDefinitionMap,        //里面的鍵就是鏈接URL,值就是存在什么條件才能訪問該鏈接        for (Iterator<Resource> it = list.iterator(); it.hasNext();) {            Resource resource = it.next();            //如果不為空值添加到section中            if(StringUtils.isNotEmpty(resource.getValue()) && StringUtils.isNotEmpty(resource.getPermission())) {                section.put(resource.getValue(),  MessageFormat.format(PREMISSION_STRING,resource.getPermission()));            }        }        return section;    }    /**     * 通過filterChainDefinitions對默認(rèn)的url過濾定義     *      * @param filterChainDefinitions 默認(rèn)的url過濾定義     */    public void setFilterChainDefinitions(String filterChainDefinitions) {        this.filterChainDefinitions = filterChainDefinitions;    }    public Class<?> getObjectType() {        return this.getClass();    }    public boolean isSingleton() {        return false;    }}

定義好了chainDefinitionSectionMetaSource后修改applicationContext-shiro.xml文件

<bean id="chainDefinitionSectionMetaSource" class="org.exitsoft.showcase.vcsadmin.service.account.ChainDefinitionSectionMetaSource">    <property name="filterChainDefinitions">        <value>            /login = authc            /logout = logout            /resource/** = anon        </value>    </property></bean><bean id="shiroSecurityFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">    <property name="securityManager" ref="securityManager" />    <property name="loginUrl" value="/login.jsp" />    <property name="successUrl" value="/index.jsp" />    <property name="unauthorizedUrl" value="/unauthorized.jsp" />    <!-- shiro連接約束配置,在這里使用自定義的動(dòng)態(tài)獲取資源類 -->    <property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" /></bean><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"></bean><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

shiro數(shù)據(jù)庫認(rèn)證、授權(quán)

在shiro認(rèn)證和授權(quán)主要是兩個(gè)類,就是org.apache.shiro.authc.AuthenticationInfo和org.apache.shiro.authz.AuthorizationInfo。該兩個(gè)類的處理在org.apache.shiro.realm.AuthorizingRealm中已經(jīng)給出了兩個(gè)抽象方法。就是:

/** * Retrieves the AuthorizationInfo for the given principals from the underlying data store.  When returning * an instance from this method, you might want to consider using an instance of * {@link org.apache.shiro.authz.SimpleAuthorizationInfo SimpleAuthorizationInfo}, as it is suitable in most cases. * * @param principals the primary identifying principals of the AuthorizationInfo that should be retrieved. * @return the AuthorizationInfo associated with this principals. * @see org.apache.shiro.authz.SimpleAuthorizationInfo */protected abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals);/** * Retrieves authentication data from an implementation-specific datasource (RDBMS, LDAP, etc) for the given * authentication token. * <p/> * For most datasources, this means just 'pulling' authentication data for an associated subject/user and nothing * more and letting Shiro do the rest.  But in some systems, this method could actually perform EIS specific * log-in logic in addition to just retrieving data - it is up to the Realm implementation. * <p/> * A {@code null} return value means that no account could be associated with the specified token. * * @param token the authentication token containing the user's principal and credentials. * @return an {@link AuthenticationInfo} object containing account data resulting from the *         authentication ONLY if the lookup is successful (i.e. account exists and is valid, etc.) * @throws AuthenticationException if there is an error acquiring data or performing *                                 realm-specific authentication logic for the specified <tt>token</tt> */protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;

doGetAuthenticationInfo(AuthenticationToken token)(認(rèn)證/登錄方法)會返回一個(gè)AuthenticationInfo,就是認(rèn)證信息。是一個(gè)對執(zhí)行及對用戶的身份驗(yàn)證(登錄)嘗試負(fù)責(zé)的方法。當(dāng)一個(gè)用戶嘗試登錄時(shí),該邏輯被認(rèn)證器執(zhí)行。認(rèn)證器知道如何與一個(gè)或多個(gè)Realm協(xié)調(diào)來存儲相關(guān)的用戶/帳戶信息。從這些Realm中獲得的數(shù)據(jù)被用來驗(yàn)證用戶的身份來保證用戶確實(shí)是他們所說的他們是誰。

doGetAuthorizationInfo(PrincipalCollection principals)是負(fù)責(zé)在應(yīng)用程序中決定用戶的訪問控制的方法。它是一種最終判定用戶是否被允許做某件事的機(jī)制。與doGetAuthenticationInfo(AuthenticationToken token)相似,doGetAuthorizationInfo(PrincipalCollection principals) 也知道如何協(xié)調(diào)多個(gè)后臺數(shù)據(jù)源來訪問角色惡化權(quán)限信息和準(zhǔn)確地決定用戶是否被允許執(zhí)行給定的動(dòng)作。

簡單的一個(gè)用戶和一個(gè)資源實(shí)體:

@Entity@Table(name="TB_RESOURCE")public class Resource implements Serializable {    //主鍵id    @Id    private String id;    //action url    private String value;    //shiro permission;    private String permission;    //------------------Getter/Setter---------------------//}

@Entity@Table(name="TB_USER")@SuppressWarnings("serial")public class User implements Serializable {    //主鍵id    @Id    private String id;    //登錄名稱    private String username;    //登錄密碼    private String password;    //擁有能訪問的資源/鏈接()    private List<Resource> resourcesList = new ArrayList<Resource>();    //-------------Getter/Setter-------------//}

@Repositorypublic class UserDao extends BasicHibernateDao<User, String> {    public User getUserByUsername(String username) {        return findUniqueByProperty("username", username);    }}

實(shí)現(xiàn)org.apache.shiro.realm.AuthorizingRealm中已經(jīng)給出了兩個(gè)抽象方法:

public class ShiroDataBaseRealm extends AuthorizingRealm{    @Autowired    private UserDao userDao;    /**     *      * 當(dāng)用戶進(jìn)行訪問鏈接時(shí)的授權(quán)方法     *      */    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {        if (principals == null) {            throw new AuthorizationException("Principal對象不能為空");        }        User user = (User) principals.fromRealm(getName()).iterator().next();        //獲取用戶響應(yīng)的permission        List<String> permissions = CollectionUtils.extractToList(user.getResourcesList(), "permission",true);        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();        info.addStringPermissions(permissions);        return info;    }    /**     * 用戶登錄的認(rèn)證方法     *      */    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;        String username = usernamePasswordToken.getUsername();        if (username == null) {            throw new AccountException("用戶名不能為空");        }        User user = userDao.getUserByUsername(username);        if (user == null) {            throw new UnknownAccountException("用戶不存在");        }        return new SimpleAuthenticationInfo(user,user.getPassword(),getName());    }}

定義好了ShiroDataBaseRealm后修改applicationContext-shiro.xml文件

<bean id="chainDefinitionSectionMetaSource" class="org.exitsoft.showcase.vcsadmin.service.account.ChainDefinitionSectionMetaSource">    <property name="filterChainDefinitions">        <value>            /login = authc            /logout = logout            /resource/** = anon        </value>    </property></bean><bean id="shiroSecurityFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">    <property name="securityManager" ref="securityManager" />    <property name="loginUrl" value="/login.jsp" />    <property name="successUrl" value="/index.jsp" />    <property name="unauthorizedUrl" value="/unauthorized.jsp" />    <!-- shiro連接約束配置,在這里使用自定義的動(dòng)態(tài)獲取資源類 -->    <property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" /></bean><bean id="shiroDataBaseRealm" class="org.exitsoft.showcase.vcsadmin.service.account.ShiroDataBaseRealm">    <!-- MD5加密 -->    <property name="credentialsMatcher">        <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">            <property name="hashAlgorithmName" value="MD5" />        </bean>    </property></bean><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">    <property name="realm" ref="shiroDataBaseRealm" /></bean><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

shiro EHcache 與 Spring EHcache集成

shiro CacheManager創(chuàng)建并管理其他Shiro組件使用的Cache實(shí)例生命周期。因?yàn)镾hiro能夠訪問許多后臺數(shù)據(jù)源,如:身份驗(yàn)證,授權(quán)和會話管理,緩存在框架中一直是一流的架構(gòu)功能,用來在同時(shí)使用這些數(shù)據(jù)源時(shí)提高性能。任何現(xiàn)代開源和/或企業(yè)的緩存產(chǎn)品能夠被插入到Shiro 來提供一個(gè)快速及高效的用戶體驗(yàn)。

自從spring 3.1問世后推出了緩存功能后,提供了對已有的 Spring 應(yīng)用增加緩存的支持,這個(gè)特性對應(yīng)用本身來說是透明的,通過緩存抽象層,使得對已有代碼的影響降低到最小。

該緩存機(jī)制針對于 Java 的方法,通過給定的一些參數(shù)來檢查方法是否已經(jīng)執(zhí)行,Spring 將對執(zhí)行結(jié)果進(jìn)行緩存,而無需再次執(zhí)行方法。

可通過下列配置來啟用緩存的支持:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:cache="http://www.springframework.org/schema/cache"   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">    <!-- 使用緩存annotation 配置 -->    <cache:annotation-driven cache-manager="ehCacheManager" /></beans>

@Cacheable@CacheEvict來對緩存進(jìn)行操作

@Cacheable:負(fù)責(zé)將方法的返回值加入到緩存中

@CacheEvict:負(fù)責(zé)清除緩存

/**聲明了一個(gè)名為 persons 的緩存區(qū)域,當(dāng)調(diào)用該方法時(shí),Spring 會檢查緩存中是否存在 personId 對應(yīng)的值。*/@Cacheable("persons")public Person profile(Long personId) { ... }/**指定多個(gè)緩存區(qū)域。Spring 會一個(gè)個(gè)的檢查,一旦某個(gè)區(qū)域存在指定值時(shí)則返回*/@Cacheable({"persons", "profiles"})public Person profile(Long personId) { ... }</code></pre><pre><code>/**清空所有緩存*/@CacheEvict(value="persons",allEntries=true)public Person profile(Long personId, Long groundId) { ... }/**或者根據(jù)條件決定是否緩存*/@CacheEvict(value="persons", condition="personId > 50")public Person profile(Long personId) { ... }

在shiro里面會有授權(quán)緩存??梢酝ㄟ^AuthorizingRealm類中指定緩存名稱。就是authorizationCacheName屬性。當(dāng)shiro為用戶授權(quán)一次之后將會把所有授權(quán)信息都放進(jìn)緩存中?,F(xiàn)在有個(gè)需求。當(dāng)在更新用戶或者刪除資源和更新資源的時(shí)候,要刷新一下shiro的授權(quán)緩存,給shiro重新授權(quán)一次。因?yàn)楫?dāng)更新用戶或者資源時(shí),很有可能已經(jīng)把用戶本身已有的資源去掉。不給用戶訪問。所以。借助spring的緩存工廠和shiro的緩存能夠很好的實(shí)現(xiàn)這個(gè)需求。

將applicationContext-shiro.xml文件添加緩存

<bean id="chainDefinitionSectionMetaSource" class="org.exitsoft.showcase.vcsadmin.service.account.ChainDefinitionSectionMetaSource">    <property name="filterChainDefinitions" >        <value>            /login = authc            /logout = logout            /resource/** = anon        </value>    </property></bean><bean id="shiroSecurityFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">    <property name="securityManager" ref="securityManager" />    <property name="loginUrl" value="/login.jsp" />    <property name="successUrl" value="/index.jsp" />    <property name="unauthorizedUrl" value="/unauthorized.jsp" />    <!-- shiro連接約束配置,在這里使用自定義的動(dòng)態(tài)獲取資源類 -->    <property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" /></bean><bean id="shiroDataBaseRealm" class="org.exitsoft.showcase.vcsadmin.service.account.ShiroDataBaseRealm">    <!-- MD5加密 -->    <property name="credentialsMatcher">        <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">            <property name="hashAlgorithmName" value="MD5" />        </bean>    </property>    <property name="authorizationCacheName" value="shiroAuthorizationCache" /></bean><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">    <property name="realm" ref="shiroDataBaseRealm" />    <property name="cacheManager" ref="cacheManager" /></bean><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/><!-- 使用緩存annotation 配置 --/><cache:annotation-driven cache-manager="ehCacheManager" /><!-- spring對ehcache的緩存工廠支持 --><bean id="ehCacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">    <property name="configLocation" value="classpath:ehcache.xml" />    <property name="shared" value="false" /></bean><!-- spring對ehcache的緩存管理 --><bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">    <property name="cacheManager" ref="ehCacheManagerFactory"></property></bean><!-- shiro對ehcache的緩存管理直接使用spring的緩存工廠 --><bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">     <property name="cacheManager" ref="ehCacheManagerFactory" /></bean>

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?><ehcache>      <!--            maxElementsInMemory為緩存對象的最大數(shù)目,             eternal設(shè)置是否永遠(yuǎn)不過期,            timeToIdleSeconds對象處于空閑狀態(tài)的最多秒數(shù),            timeToLiveSeconds對象處于緩存狀態(tài)的最多秒數(shù)      -->    <diskStore path="java.io.tmpdir"/>    <cache name="shiroAuthorizationCache" maxElementsInMemory="300" eternal="false" timeToLiveSeconds="600" overflowToDisk="false"/></ehcache>

public class UserDao extends BasicHibernateDao<User, String> {    public User getUserByUsername(String username) {        return findUniqueByProperty("username", username);    }    @CacheEvict(value="shiroAuthorizationCache",allEntries=true)    public void saveUser(User entity) {        save(entity);    }}

@Repositorypublic class ResourceDao extends BasicHibernateDao<Resource, String> {    @CacheEvict(value="shiroAuthorizationCache",allEntries=true)    public void saveResource(Resource entity) {        save(entity);    }    @CacheEvict(value="shiroAuthorizationCache",allEntries=true)    public void deleteResource(Resource entity) {        delete(entity);    }}

當(dāng)userDao或者reaourceDao調(diào)用了相應(yīng)帶有緩存注解的方法,都會將AuthorizingRealm類中的緩存去掉。那么就意味著 shiro在用戶訪問鏈接時(shí)要重新授權(quán)一次。

整個(gè)apache shiro的使用在basic-curd項(xiàng)目有例子。可以參考showcase/basic-curd項(xiàng)目中的例子去理解。。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Shiro 緩存失效以后的一個(gè)問題
springrain技術(shù)詳解(1)
Apache shiro集群實(shí)現(xiàn) (六)分布式集群系統(tǒng)下的高可用session解決方案
shiro實(shí)現(xiàn)不同身份使用不同Realm進(jìn)行驗(yàn)證
將 Shiro 作為應(yīng)用的權(quán)限基礎(chǔ) 四:shiro的配置說明
shiro用authc配置url和用注解@RequiresAuthentication的問題
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服