springboot + shiro動態權限

此處不再說明springboot集成shiro相關內容,如有不懂集成的可以搜素相關帖子。
場景:多項目管理中,各個項目分配給同一個賬號不同權限,在進行項目切換中權限會統一查詢導致權限範圍蔓延擴大,需要進行項目級的權限隔離;

1、首先在ShiroConfig中設置ShiroRealm的名稱(可以省略,但是建議設置),此處設置後再後續清除緩存時需要用到;

@Bean
public ShiroRealm shiroRealm() {
    ShiroRealm shiroRealm = new ShiroRealm();
    //此處設置緩存信息在緩存中的名稱
    shiroRealm.setName("mpm");
    shiroRealm.setCacheManager(cacheManager());
    return shiroRealm;
}

2、在ShiroRealm中對doGetAuthorizationInfo 方法進行改造,需要在查詢權限時根據當前的項目進行查詢;當然此方法在項目中只觸發一次(未清除shiro緩存情況下)

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    UserModel loginModel = (UserModel) principalCollection.getPrimaryPrincipal();
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    if (loginModel.getIsAdmin() != null && loginModel.getIsAdmin()) {
        info.addStringPermission("*:*");
        return info;
    }
    //此處需要提前緩存切換的項目id,否則獲取不到當前項目
    //根據項目id查詢用戶在項目下的角色所屬的資源信息
    Long projectId = Long.valueOf((String.valueOf(SecurityUtils.getSubject().getSession().getAttribute("projectId"))));
    List<String> permissionList = new ArrayList<>();
    if (projectId == null) {
        permissionList = this.resourceService.selectResourceByUserId(loginModel.getId());
    } else {
        permissionList = this.resourceService.selectResourceByUserIdAndProjectId(loginModel.getId(), projectId);
    }
    info.addStringPermissions(permissionList);
    return info;
}

3、在前端頁面進行項目切換時,請求後臺過程中進行權限緩存清除。shiro在進行權限校驗時優先查詢緩存信息,如沒有緩存信息會觸發doGetAuthorizationInfo 方法進行初始化後存入緩存中;
在需要清除緩存的類中注入shiro集成的緩存服務,如當前項目集成的是CacheManager;在切換方法中執行清除緩存,如此可以實現動態權限;

//緩存名稱的前綴mpm在ShiroConfig中設置 後綴.authorizationCache爲shiro默認的後綴名稱
//這個方法的用途是清除當前用戶的授權緩存信息 SecurityUtils.getSubject().getPrincipals()獲取的是當前用戶信息對象
cacheManager.getCache("mpm.authorizationCache").remove(SecurityUtils.getSubject().getPrincipals());

如此,大功告成;

發佈了8 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章