Shiro(2)---授權

Shiro授權

1.授權流程

這裏寫圖片描述

2.授權方式

Shiro 支持三種方式的授權:

1.編程式:通過寫if/else 授權代碼塊完成:

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有權限
} else {
//無權限
}

2.註解式:通過在執行的Java方法上放置相應的註解完成:

@RequiresRoles("admin")
public void hello() {
//有權限的操作
}

3.JSP/GSP 標籤:在JSP/GSP 頁面通過相應的標籤完成:####  

<shiro:hasRole name="admin">
<!— 有權限—>
</shiro:hasRole>

3.入門測試程序

測試分爲基於角色的權限控制和基於資源的權限控制(開發中建議使用)

1. 創建shiro-permission.ini文件模擬數據源

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

#權限
[roles]
#角色role1對資源user擁有createupdate權限
role1=user:create,user:update
#角色role2對資源user擁有createdelete權限
role2=user:create,user:delete
#角色role3對資源user擁有create權限
role3=user:create

權限標識符號規則:資源:操作:實例(中間使用半角:分隔)
user:create:01 表示對用戶資源的01實例進行create操作。
user:create 表示對用戶資源進行create操作,相當於user:create:*,對所有用戶資源實例進行create操作。
user:*:01 表示對用戶資源實例01進行所有操作。

2. 測試代碼

public void testPermission(){
        //根據ini文件創建SecurityManagerFactory
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
        SecurityManager securityManager = factory.getInstance();
        //將securityManager設置到運行環境中
        SecurityUtils.setSecurityManager(securityManager);
        //創建主體對象
        Subject subject = SecurityUtils.getSubject();
        //有身份和憑證信息生成一個token
        UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }
        boolean isAuthenticated = subject.isAuthenticated();
        System.out.println("用戶認證狀態: "+isAuthenticated);
        //基於角色的權限控制
        boolean isHasRole1 = subject.hasRole("role1");
        System.out.println("是否有role1角色: "+isHasRole1);
        boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1","role2","role3"));
        System.out.println("是否有所有角色: "+hasAllRoles);
        //使用check進行授權,如果授權失敗則拋異常
        subject.checkRole("role1");
        subject.checkRoles("role1","role2");
        //基於資源的權限控制
        boolean isPermitted = subject.isPermitted("user:create");
        System.out.println("是否擁有該權限: "+isPermitted);
        boolean isPermittedAll = subject.isPermittedAll("user:create:1","user:delete");
        System.out.println("是否擁有所有的權限: "+isPermittedAll);
        //使用check進行授權,如果授權失敗則拋異常
        subject.checkPermission("user:create");
        subject.checkPermissions("user:create","user:delete");
    }

4.自定義realm

這裏用到的是基於資源的權限控制
1.在自定義realm完善doGetAuthorizationInfo()方法

// 授權
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        //獲取身份信息
        String principal = (String)principals.getPrimaryPrincipal();
        //根據身份信息從數據庫中獲取權限數據
        //使用靜態數據進行模擬...
        List<String> permissions = new ArrayList<String>();
        permissions.add("user:create");
        permissions.add("user:delete");
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //將權限數據封裝到SimpleAuthorizationInfo對象中
simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

2.ini配置文件還使用認證階段使用的,不用改變。

[main]
#自定義realm
customRealm=com.ak.shiro.CustomRealm
#將realm設置到securityManager
securityManager.realms=$customRealm

5.授權流程

1、對subject進行授權,調用方法isPermitted(”permission串”)

2、SecurityManager執行授權,通過ModularRealmAuthorizer執行授權

3、ModularRealmAuthorizer執行realm(自定義的CustomRealm)從數據庫查詢權限數據
  調用realm的授權方法:doGetAuthorizationInfo

4、realm從數據庫查詢權限數據,並返回給ModularRealmAuthorizer

5、ModularRealmAuthorizer調用PermissionResolver進行權限串比對

6、如果比對後,isPermitted中”permission串”在realm查詢到權限數據中,說明用戶訪問permission串有權限,否則 沒有權限,拋出異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章