国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Shiro【授權(quán)、整合Spirng、Shiro過濾器】

ralap / 2727人閱讀

摘要:表示對(duì)用戶資源進(jìn)行操作,相當(dāng)于,對(duì)所有用戶資源實(shí)例進(jìn)行操作。與整合,實(shí)際上的操作都是通過過濾器來干的。將安全管理器交由工廠來進(jìn)行管理。在過濾器鏈中設(shè)置靜態(tài)資源不攔截。

前言

本文主要講解的知識(shí)點(diǎn)有以下:

Shiro授權(quán)的方式簡(jiǎn)單介紹

與Spring整合

初始Shiro過濾器

一、Shiro授權(quán)

上一篇我們已經(jīng)講解了Shiro的認(rèn)證相關(guān)的知識(shí)了,現(xiàn)在我們來弄Shiro的授權(quán)

Shiro授權(quán)的流程和認(rèn)證的流程其實(shí)是差不多的:

1.1Shiro支持的授權(quán)方式

Shiro支持的授權(quán)方式有三種:

Shiro 支持三種方式的授權(quán):
?編程式:通過寫if/else 授權(quán)代碼塊完成:
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有權(quán)限
} else {
//無權(quán)限
}
?注解式:通過在執(zhí)行的Java方法上放置相應(yīng)的注解完成:
@RequiresRoles("admin")
public void hello() {
//有權(quán)限
}
?JSP/GSP 標(biāo)簽:在JSP/GSP 頁面通過相應(yīng)的標(biāo)簽完成:


1.2使用編程式授權(quán)

同樣的,我們是通過安全管理器來去授權(quán)的,因此我們還是需要配置對(duì)應(yīng)的配置文件的:

shiro-permission.ini配置文件:

#用戶
[users]
#用戶zhang的密碼是123,此用戶具有role1和role2兩個(gè)角色
zhang=123,role1,role2
wang=123,role2

#權(quán)限
[roles]
#角色role1對(duì)資源user擁有create、update權(quán)限
role1=user:create,user:update
#角色role2對(duì)資源user擁有create、delete權(quán)限
role2=user:create,user:delete
#角色role3對(duì)資源user擁有create權(quán)限
role3=user:create



#權(quán)限標(biāo)識(shí)符號(hào)規(guī)則:資源:操作:實(shí)例(中間使用半角:分隔)
user:create:01  表示對(duì)用戶資源的01實(shí)例進(jìn)行create操作。
user:create:表示對(duì)用戶資源進(jìn)行create操作,相當(dāng)于user:create:*,對(duì)所有用戶資源實(shí)例進(jìn)行create操作。
user:*:01  表示對(duì)用戶資源實(shí)例01進(jìn)行所有操作。

代碼測(cè)試:


    // 角色授權(quán)、資源授權(quán)測(cè)試
    @Test
    public void testAuthorization() {

        // 創(chuàng)建SecurityManager工廠
        Factory factory = new IniSecurityManagerFactory(
                "classpath:shiro-permission.ini");

        // 創(chuàng)建SecurityManager
        SecurityManager securityManager = factory.getInstance();

        // 將SecurityManager設(shè)置到系統(tǒng)運(yùn)行環(huán)境,和spring后將SecurityManager配置spring容器中,一般單例管理
        SecurityUtils.setSecurityManager(securityManager);

        // 創(chuàng)建subject
        Subject subject = SecurityUtils.getSubject();

        // 創(chuàng)建token令牌
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
                "123");

        // 執(zhí)行認(rèn)證
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("認(rèn)證狀態(tài):" + subject.isAuthenticated());
        // 認(rèn)證通過后執(zhí)行授權(quán)

        // 基于角色的授權(quán)
        // hasRole傳入角色標(biāo)識(shí)
        boolean ishasRole = subject.hasRole("role1");
        System.out.println("單個(gè)角色判斷" + ishasRole);
        // hasAllRoles是否擁有多個(gè)角色
        boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1",
                "role2", "role3"));
        System.out.println("多個(gè)角色判斷" + hasAllRoles);

        // 使用check方法進(jìn)行授權(quán),如果授權(quán)不通過會(huì)拋出異常
        // subject.checkRole("role13");

        // 基于資源的授權(quán)
        // isPermitted傳入權(quán)限標(biāo)識(shí)符
        boolean isPermitted = subject.isPermitted("user:create:1");
        System.out.println("單個(gè)權(quán)限判斷" + isPermitted);

        boolean isPermittedAll = subject.isPermittedAll("user:create:1",
                "user:delete");
        System.out.println("多個(gè)權(quán)限判斷" + isPermittedAll);
        // 使用check方法進(jìn)行授權(quán),如果授權(quán)不通過會(huì)拋出異常
        subject.checkPermission("items:create:1");

    }
1.3自定義realm進(jìn)行授權(quán)

一般地,我們的權(quán)限都是從數(shù)據(jù)庫中查詢的,并不是根據(jù)我們的配置文件來進(jìn)行配對(duì)的。因此我們需要自定義reaml,讓reaml去對(duì)比的是數(shù)據(jù)庫查詢出來的權(quán)限

shiro-realm.ini配置文件:將自定義的reaml信息注入到安全管理器中

[main]
#自定義 realm
customRealm=cn.itcast.shiro.realm.CustomRealm
#將realm設(shè)置到securityManager,相當(dāng) 于spring中注入
securityManager.realms=$customRealm



我們上次已經(jīng)使用過了一個(gè)自定義reaml,當(dāng)時(shí)候僅僅重寫了doGetAuthenticationInfo()方法,這次我們重寫doGetAuthorizationInfo()方法

    // 用于授權(quán)
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        
        //從 principals獲取主身份信息
        //將getPrimaryPrincipal方法返回值轉(zhuǎn)為真實(shí)身份類型(在上邊的doGetAuthenticationInfo認(rèn)證通過填充到SimpleAuthenticationInfo中身份類型),
        String userCode =  (String) principals.getPrimaryPrincipal();
        
        //根據(jù)身份信息獲取權(quán)限信息
        //連接數(shù)據(jù)庫...
        //模擬從數(shù)據(jù)庫獲取到數(shù)據(jù)
        List permissions = new ArrayList();
        permissions.add("user:create");//用戶的創(chuàng)建
        permissions.add("items:add");//商品添加權(quán)限
        //....
        
        //查到權(quán)限數(shù)據(jù),返回授權(quán)信息(要包括 上邊的permissions)
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //將上邊查詢到授權(quán)信息填充到simpleAuthorizationInfo對(duì)象中
        simpleAuthorizationInfo.addStringPermissions(permissions);

        return simpleAuthorizationInfo;
    }

測(cè)試程序:

    // 自定義realm進(jìn)行資源授權(quán)測(cè)試
    @Test
    public void testAuthorizationCustomRealm() {

        // 創(chuàng)建SecurityManager工廠
        Factory factory = new IniSecurityManagerFactory(
                "classpath:shiro-realm.ini");
        // 創(chuàng)建SecurityManager
        SecurityManager securityManager = factory.getInstance();
        // 將SecurityManager設(shè)置到系統(tǒng)運(yùn)行環(huán)境,和spring后將SecurityManager配置spring容器中,一般單例管理
        SecurityUtils.setSecurityManager(securityManager);
        // 創(chuàng)建subject
        Subject subject = SecurityUtils.getSubject();

        // 創(chuàng)建token令牌
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
                "111111");
        // 執(zhí)行認(rèn)證
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("認(rèn)證狀態(tài):" + subject.isAuthenticated());
        // 認(rèn)證通過后執(zhí)行授權(quán)

        // 基于資源的授權(quán),調(diào)用isPermitted方法會(huì)調(diào)用CustomRealm從數(shù)據(jù)庫查詢正確權(quán)限數(shù)據(jù)
        // isPermitted傳入權(quán)限標(biāo)識(shí)符,判斷user:create:1是否在CustomRealm查詢到權(quán)限數(shù)據(jù)之內(nèi)
        boolean isPermitted = subject.isPermitted("user:create:1");
        System.out.println("單個(gè)權(quán)限判斷" + isPermitted);

        boolean isPermittedAll = subject.isPermittedAll("user:create:1",
                "user:create");
        System.out.println("多個(gè)權(quán)限判斷" + isPermittedAll);

        // 使用check方法進(jìn)行授權(quán),如果授權(quán)不通過會(huì)拋出異常
        subject.checkPermission("items:add:1");

    }

二、Spring與Shiro整合 2.1導(dǎo)入jar包

shiro-web的jar、

shiro-spring的jar

shiro-code的jar

2.2快速入門

shiro也通過filter進(jìn)行攔截。filter攔截后將操作權(quán)交給spring中配置的filterChain(過慮鏈兒)

在web.xml中配置filter


    
    
        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
        
        
            targetFilterLifecycle
            true
        
        
        
            targetBeanName
            shiroFilter
        
    
    
        shiroFilter
        /*
    

applicationContext-shiro.xml 中配置web.xml中fitler對(duì)應(yīng)spring容器中的bean



    
        
        
        
        
        
        
        
        
        
            
                
                
            
        
        
        
        
            
                
                /** = anon
            
        
    

配置安全管理器



            

配置reaml



步驟:

在web.xml文件中配置shiro的過濾器

在對(duì)應(yīng)的Spring配置文件中配置與之對(duì)應(yīng)的filterChain(過慮鏈兒)

配置安全管理器,注入自定義的reaml

配置自定義的reaml

2.3靜態(tài)資源不攔截

我們?cè)趕pring配置過濾器鏈的時(shí)候,我們發(fā)現(xiàn)這么一行代碼:

    
     /** = anon

anon其實(shí)就是shiro內(nèi)置的一個(gè)過濾器,上邊的代碼就代表著所有的匿名用戶都可以訪問

當(dāng)然了,后邊我們還需要配置其他的信息,為了讓頁面能夠正常顯示,我們的靜態(tài)資源一般是不需要被攔截的

于是我們可以這樣配置:

    
    /images/** = anon
    /js/** = anon
    /styles/** = anon
三、初識(shí)shiro過濾器

上面我們了解到了anno過濾器的,shiro還有其他的過濾器的..我們來看看

常用的過濾器有下面幾種:

anon:例子/admins/**=anon 沒有參數(shù),表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要認(rèn)證(登錄)才能使用,F(xiàn)ormAuthenticationFilter是表單認(rèn)證,沒有參數(shù)
perms:例子/admins/user/**=perms[user:add:*],參數(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()方法。
user:例如/admins/user/**=user沒有參數(shù),表示必須存在用戶, 身份認(rèn)證通過或通過記住我認(rèn)證通過的可以訪問,當(dāng)?shù)侨氩僮鲿r(shí)不做檢查

3.1登陸與退出

使用FormAuthenticationFilter過慮器實(shí)現(xiàn) ,原理如下:

當(dāng)用戶沒有認(rèn)證時(shí),請(qǐng)求loginurl進(jìn)行認(rèn)證【上邊我們已經(jīng)配置了】,用戶身份和用戶密碼提交數(shù)據(jù)到loginurl

FormAuthenticationFilter攔截住取出request中的username和password(兩個(gè)參數(shù)名稱是可以配置的

FormAuthenticationFilter 調(diào)用realm傳入一個(gè)token(username和password)

realm認(rèn)證時(shí)根據(jù)username查詢用戶信息(在Activeuser中存儲(chǔ),包括 userid、usercode、username、menus)。

如果查詢不到,realm返回null,F(xiàn)ormAuthenticationFilter向request域中填充一個(gè)參數(shù)(記錄了異常信息)

查詢出用戶的信息之后,F(xiàn)ormAuthenticationFilter會(huì)自動(dòng)將reaml返回的信息和token中的用戶名和密碼對(duì)比。如果不對(duì),那就返回異常。

3.1.1登陸頁面

由于FormAuthenticationFilter的用戶身份和密碼的input的默認(rèn)值(username和password)修改頁面的賬號(hào)和密碼的input的名稱為username和password

    
        用戶名:
        
    
    
        密 碼:
        
        
    
3.1.2登陸代碼實(shí)現(xiàn)

上面我們已經(jīng)說了,當(dāng)用戶沒有認(rèn)證的時(shí)候,請(qǐng)求的loginurl進(jìn)行認(rèn)證,用戶身份的用戶密碼提交數(shù)據(jù)到loginrul中

當(dāng)我們提交到loginurl的時(shí)候,表單過濾器會(huì)自動(dòng)解析username和password去調(diào)用realm來進(jìn)行認(rèn)證。最終在request域?qū)ο笾写鎯?chǔ)shiroLoginFailure認(rèn)證信息,如果返回的是異常的信息,那么我們?cè)趌ogin中拋出異常即可


//登陸提交地址,和applicationContext-shiro.xml中配置的loginurl一致
    @RequestMapping("login")
    public String login(HttpServletRequest request)throws Exception{
        
        //如果登陸失敗從request中獲取認(rèn)證異常信息,shiroLoginFailure就是shiro異常類的全限定名
        String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
        //根據(jù)shiro返回的異常類路徑判斷,拋出指定異常信息
        if(exceptionClassName!=null){
            if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
                //最終會(huì)拋給異常處理器
                throw new CustomException("賬號(hào)不存在");
            } else if (IncorrectCredentialsException.class.getName().equals(
                    exceptionClassName)) {
                throw new CustomException("用戶名/密碼錯(cuò)誤");
            } else if("randomCodeError".equals(exceptionClassName)){
                throw new CustomException("驗(yàn)證碼錯(cuò)誤 ");
            }else {
                throw new Exception();//最終在異常處理器生成未知錯(cuò)誤
            }
        }
        //此方法不處理登陸成功(認(rèn)證成功),shiro認(rèn)證成功會(huì)自動(dòng)跳轉(zhuǎn)到上一個(gè)請(qǐng)求路徑
        //登陸失敗還到login頁面
        return "login";
    }

配置認(rèn)證過濾器

    
        
        /images/** = anon
        /js/** = anon
        /styles/** = anon

        
        /** = authc
    
3.2退出

不用我們?nèi)?shí)現(xiàn)退出,只要去訪問一個(gè)退出的url(該 url是可以不存在),由LogoutFilter攔截住,清除session。

在applicationContext-shiro.xml配置LogoutFilter:

        
        /logout.action = logout
四、認(rèn)證后信息在頁面顯示

1、認(rèn)證后用戶菜單在首頁顯示
2、認(rèn)證后用戶的信息在頁頭顯示

realm從數(shù)據(jù)庫查詢用戶信息,將用戶菜單、usercode、username等設(shè)置在SimpleAuthenticationInfo中。

    //realm的認(rèn)證方法,從數(shù)據(jù)庫查詢用戶信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        
        // token是用戶輸入的用戶名和密碼 
        // 第一步從token中取出用戶名
        String userCode = (String) token.getPrincipal();

        // 第二步:根據(jù)用戶輸入的userCode從數(shù)據(jù)庫查詢
        SysUser sysUser = null;
        try {
            sysUser = sysService.findSysUserByUserCode(userCode);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        // 如果查詢不到返回null
        if(sysUser==null){//
            return null;
        }
        // 從數(shù)據(jù)庫查詢到密碼
        String password = sysUser.getPassword();
        
        //鹽
        String salt = sysUser.getSalt();

        // 如果查詢到返回認(rèn)證信息AuthenticationInfo
        
        //activeUser就是用戶身份信息
        ActiveUser activeUser = new ActiveUser();
        
        activeUser.setUserid(sysUser.getId());
        activeUser.setUsercode(sysUser.getUsercode());
        activeUser.setUsername(sysUser.getUsername());
        //..
        
        //根據(jù)用戶id取出菜單
        List menus  = null;
        try {
            //通過service取出菜單 
            menus = sysService.findMenuListByUserId(sysUser.getId());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //將用戶菜單 設(shè)置到activeUser
        activeUser.setMenus(menus);

        //將activeUser設(shè)置simpleAuthenticationInfo
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                activeUser, password,ByteSource.Util.bytes(salt), this.getName());

        return simpleAuthenticationInfo;
    }

配置憑配器,因?yàn)槲覀冇玫搅薽d5和散列



    
    


    
    

在跳轉(zhuǎn)到首頁的時(shí)候,取出用戶的認(rèn)證信息,轉(zhuǎn)發(fā)到JSP即可

    //系統(tǒng)首頁
    @RequestMapping("/first")
    public String first(Model model)throws Exception{
        
        //從shiro的session中取activeUser
        Subject subject = SecurityUtils.getSubject();
        //取身份信息
        ActiveUser activeUser = (ActiveUser) subject.getPrincipal();
        //通過model傳到頁面
        model.addAttribute("activeUser", activeUser);
        
        return "/first";
    }
五、總結(jié)

Shiro用戶權(quán)限有三種方式

編程式

注解式

標(biāo)簽式

Shiro的reaml默認(rèn)都是去找配置文件的信息來進(jìn)行授權(quán)的,我們一般都是要reaml去數(shù)據(jù)庫來查詢對(duì)應(yīng)的信息。因此,又需要自定義reaml

總體上,認(rèn)證和授權(quán)的流程差不多。

Spring與Shiro整合,Shiro實(shí)際上的操作都是通過過濾器來干的。Shiro為我們提供了很多的過濾器。

在web.xml中配置Shiro過濾器

在Shiro配置文件中使用web.xml配置過的過濾器。

配置安全管理器類,配置自定義的reaml,將reaml注入到安全管理器類上。將安全管理器交由Shiro工廠來進(jìn)行管理。

在過濾器鏈中設(shè)置靜態(tài)資源不攔截。

在Shiro使用過濾器來進(jìn)行用戶認(rèn)證,流程是這樣子的:

配置用于認(rèn)證的請(qǐng)求路徑

當(dāng)訪問程序員該請(qǐng)求路徑的時(shí)候,Shiro會(huì)使用FormAuthenticationFilter會(huì)調(diào)用reaml獲得用戶的信息

reaml可以拿到token,通過用戶名從數(shù)據(jù)庫獲取得到用戶的信息,如果用戶不存在則返回null

FormAuthenticationFilter會(huì)將reaml返回的數(shù)據(jù)進(jìn)行對(duì)比,如果不同則拋出異常

我們的請(qǐng)求路徑僅僅是用來檢測(cè)有沒有異常拋出,并不用來做校驗(yàn)的。

shiro還提供了退出用戶的攔截器,我們配置一個(gè)url就行了。

當(dāng)需要獲取用戶的數(shù)據(jù)用于回顯的時(shí)候,我們可以在SecurityUtils.getSubject()來得到主體,再通過主體拿到身份信息。

如果文章有錯(cuò)的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號(hào):Java3y

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/68880.html

相關(guān)文章

  • Java3y文章目錄導(dǎo)航

    摘要:前言由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會(huì)更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號(hào):Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡(jiǎn)單 注解就這么簡(jiǎn)單 Druid數(shù)據(jù)庫連接池...

    KevinYan 評(píng)論0 收藏0
  • Shiro授權(quán)濾器、與ehcache整合、驗(yàn)證碼、記住我】

    摘要:為了達(dá)到很好的效果,我們使用來對(duì)的緩存進(jìn)行管理配置會(huì)話管理器,對(duì)會(huì)話時(shí)間進(jìn)行控制手動(dòng)清空緩存由于驗(yàn)證用戶名和密碼之前,一般需要驗(yàn)證驗(yàn)證碼的。 前言 本文主要講解的知識(shí)點(diǎn)有以下: Shiro授權(quán)過濾器使用 Shiro緩存 與Ehcache整合 Shiro應(yīng)用->實(shí)現(xiàn)驗(yàn)證碼功能 記住我功能 一、授權(quán)過濾器測(cè)試 我們的授權(quán)過濾器使用的是permissionsAuthorization...

    K_B_Z 評(píng)論0 收藏0
  • Spring Boot 整合 Shiro

    摘要:雖然,直接用和進(jìn)行全家桶式的合作是最好不過的,但現(xiàn)實(shí)總是欺負(fù)我們這些沒辦法決定架構(gòu)類型的娃子。并非按輸入順序。遍歷時(shí)只能全部輸出,而沒有順序。設(shè)想以下,若全局劫持在最前面,那么只要在襠下的,都早早被劫持了。底層是數(shù)組加單項(xiàng)鏈表加雙向鏈表。 雖然,直接用Spring Security和SpringBoot 進(jìn)行全家桶式的合作是最好不過的,但現(xiàn)實(shí)總是欺負(fù)我們這些沒辦法決定架構(gòu)類型的娃子。 Apa...

    newsning 評(píng)論0 收藏0
  • apache shiro框架

    摘要:框架提供的接口,是的核心,代表安全管理器對(duì)象。可以開發(fā)人員編寫,框架也提供一些。在中作為應(yīng)用程序和安全數(shù)據(jù)之間的橋梁或連接器。例如要求中必須同時(shí)含有和的權(quán)限才能執(zhí)行方法。 apache shiro框架簡(jiǎn)介  Apache Shiro是一個(gè)強(qiáng)大而靈活的開源安全框架,它能夠干凈利落地處理身份認(rèn)證,授權(quán),企業(yè)會(huì)話管理和加密。現(xiàn)在,使用Apache Shiro的人越來越多,因?yàn)樗喈?dāng)簡(jiǎn)單,相比比Sp...

    Tecode 評(píng)論0 收藏0
  • springboot整合shiro使用shiro-spring-boot-web-starter

    摘要:此文章僅僅說明在整合時(shí)的一些坑并不是教程增加依賴集成依賴配置三個(gè)必須的用于授權(quán)和登錄創(chuàng)建自己的實(shí)例用于實(shí)現(xiàn)權(quán)限三種方式實(shí)現(xiàn)定義權(quán)限路徑第一種使用角色名定義第二種使用權(quán)限定義第三種使用接口的自定義配置此處配置之后需要在對(duì)應(yīng)的 此文章僅僅說明在springboot整合shiro時(shí)的一些坑,并不是教程 增加依賴 org.apache.shiro shiro-spring-...

    sevi_stuo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<