shiro受權流程

開始正題前,先談談對繼承與實現的一點點理解,敲了三年代碼終於理解一點點繼承與實現的妙用了,繼承就是把你們公共的方法提作父類的方法,後面只要繼承這個父類,就擁有了父類的全部方法,這樣就減小了不少冗餘代碼; 實現就是接口先規範一些方法,我要調用接口裏的方法幫我作一些事情,這時我並不知道這個方法具體是怎麼實現的,後面我能夠用各類不一樣的方式實現這個接口的方法,實現了哪一個前面實際就調用哪一個。 如下是實際舉例: 1shiro的AuthorizingRealm類調用了接口PermissionResolver的resolvePermission方法把字符串轉換成相應的Permission實例,這個時候它雖然調用了,可是它不知道具體是怎麼轉的。須要咱們告訴它,因而,咱們要實現接口PermissionResolver的resolvePermission方法,以下:java

public class BitAndWildPermissionResolver implements PermissionResolver {
    @Override
    public Permission resolvePermission(String permissionString) {
        if(permissionString.startsWith("+")) {
            return new BitPermission(permissionString);
        }
        return new WildcardPermission(permissionString);
    }
}

RolePermissionResolver 的方法resolvePermissionsInRole同理。ide

1、受權流程code

一、驗證主體是否擁有某些權限,無非是調用如下幾個方法進行判斷:繼承

hasRole,hasAllRoles,hasRoles,checkRole,checkRoles isPermitted,isPermittedAll,checkPermission,checkPermissions接口

二、首先調用Subject.isPermitted*/hasRole接口,其會委託給SecurityManager,而SecurityManager接着會委託給Authorizer;即最後誰實現了Authorizer的isPermitted/hasRole,調用的就是誰。shiro中Authorizer具體實現類有以下:圖片

輸入圖片說明

三、Authorizer是真正的受權者,若是咱們調用如isPermitted(「user:view」),其首先會經過PermissionResolver把字符串轉換成相應的Permission實例;如類AuthorizingRealm調用了resolvePermission方法把字符串轉換成相應的Permission實例。ip

public boolean isPermitted(PrincipalCollection principals, String permission) {
        Permission p = getPermissionResolver().resolvePermission(permission);
        return isPermitted(principals, p);
    }

resolvePermission方法要本身去實現,如:ci

public class BitAndWildPermissionResolver implements PermissionResolver {
    @Override
    public Permission resolvePermission(String permissionString) {
        if(permissionString.startsWith("+")) {
            return new BitPermission(permissionString);
        }
        return new WildcardPermission(permissionString);
    }
}

四、在進行受權以前,其會調用相應的Realm獲取Subject相應的角色/權限用於匹配傳入的角色/權限;如AuthorizingRealm類作了的以下這些事情,這裏它調用getAuthorizationInfo方法獲取Subject相應的角色/權限。字符串

public boolean isPermitted(PrincipalCollection principals, String permission) {
        Permission p = getPermissionResolver().resolvePermission(permission);
        return isPermitted(principals, p);
    }
public boolean isPermitted(PrincipalCollection principals, Permission permission) {
        AuthorizationInfo info = getAuthorizationInfo(principals);
        return isPermitted(permission, info);
    }
private boolean isPermitted(Permission permission, AuthorizationInfo info) {
        Collection<Permission> perms = getPermissions(info);
        if (perms != null && !perms.isEmpty()) {
            for (Permission perm : perms) {
                if (perm.implies(permission)) {
                    return true;
                }
            }
        }
        return false;
    }

五、Authorizer會判斷Realm的角色/權限是否和傳入的匹配,若是有多個Realm,會委託給ModularRealmAuthorizer進行循環判斷,若是匹配如isPermitted*/hasRole*會返回true,不然返回false表示受權失敗。get

輸入圖片說明

public boolean isPermitted(PrincipalCollection principals, String permission) {
        assertRealmsConfigured();
        for (Realm realm : getRealms()) {
            if (!(realm instanceof Authorizer)) continue;
            if (((Authorizer) realm).isPermitted(principals, permission)) {
                return true;
            }
        }
        return false;
    }

ModularRealmAuthorizer進行多Realm匹配流程:

一、首先檢查相應的Realm是否實現了實現了Authorizer;

二、若是實現了Authorizer,那麼接着調用其相應的isPermitted*/hasRole*接口進行匹配;

三、若是有一個Realm匹配那麼將返回true,不然返回false。

總結:Authorizer的職責是進行受權(訪問控制),是Shiro API中受權核心的入口點,其提供了相應的角色/權限判斷接口。SecurityManager繼承了Authorizer接口,且提供了ModularRealmAuthorizer用於多Realm時的受權匹配。PermissionResolver用於解析權限字符串到Permission實例,而RolePermissionResolver用於根據角色解析相應的權限集合。

相關文章
相關標籤/搜索