shiro自定義權限標籤的坑

shiro遇到的坑

-項目中使用shiro做登錄校驗和權限管理,在配置權限時遇到小坑,記錄一下。

環境:springboot+freemarker+shiro
場景:後臺管理,配置菜單以及按鈕權限,分爲三個層級,一二級暫時只考慮是否查看權限,第三層級爲頁面按鈕權限,分增刪改查。詳情看圖

問題:一二層級正常,第三層級權限不起作用!

權限標籤定義如下:

標籤定義 頁面一 頁面二
第一層級 one:view two:view
第二層級 one:page1:view two:page2:view
第三層級 one:page1:view:add two:page2:view:add

開始懷疑是數據庫沒有錄入,查看後權限標籤與角色已對應,排除。

後面懷疑是頁面問題,後面把第三層級標籤與第一二層級同一頁面,依然不起作用,排除。

後面懷疑是權限標籤定義問題,把第三層級標籤改爲one:page1:data:add,奇蹟出現,權限生效。證實權限標籤定義出了問題。

問題原因:權限標籤定義問題

但是後來想想爲什麼會出現這種問題,每個標籤都是獨一無二的,對此我對shiro對於權限標籤的校驗產生了興趣,查看源碼,一路debug後最終在org.apache.shiro.authz.permission中看到了關鍵所在,核心代碼如下

、、、
//當這個方法返回true時說明有此權限
//這個p是代表當前循環匹配到的權限標籤
public boolean implies(Permission p) {
// By default only supports comparisons with other WildcardPermissions
if (!(p instanceof WildcardPermission)) {
return false;
}

    WildcardPermission wp = (WildcardPermission) p;
    //把當前標籤轉分割成一個set集合(如one:page1:view:add 會分割成[[one], [page1], [view], [add]])
    List<Set<String>> otherParts = wp.getParts();

    int i = 0;
    //循環匹配權限標籤
    for (Set<String> otherPart : otherParts) {
        // If this permission has less parts than the other permission, everything after the number of parts contained
        // in this permission is automatically implied, so return true
        //當全部循環匹配完沒有返回false,則返回true,這個getparts()方法是獲取當前角色當前循環的權限標籤([[one], [page1], [view]])
        if (getParts().size() - 1 < i) {
            return true;
        } else {
            Set<String> part = getParts().get(i);
            /*如果包含有‘*’而且不包含當前分割後的標籤則返回false,
             *當用戶可以查看頁面,也就是說當前角色擁有one:page1:view標籤
             *這裏【!part.contains(WILDCARD_TOKEN)】返回true,第二個【part.containsAll(otherPart)】one會跟當前標籤匹**配one,
             *也就是說這裏全部循環完返回的都是false,所以最後都沒true,於是在上面返回了一個true。
            if (!part.contains(WILDCARD_TOKEN) && !part.containsAll(otherPart)) {
                return false;
            }
            i++;
        }
    }

、、、

總結:通過分析,我們看到了shiro在定義權限標籤時,要主意匹配問題,不要存在包含問題,類似aaa 和aaab ,會導致後面標籤失效。

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