使用shiro時遇到一個問題,想為多個角色分配同一權限,也就是只要滿足其中一個角色,就可以獲得該權限,多角色之間是or關系而非and,但是shiro自帶的方法同一權限只能分配一個角色。
1 // 使用如下Shiro自帶的方法實現多角色權限分配,無法實現 2 filterChainDefinitionMap.put("/user/**", "roles[admin]"); 3 filterChainDefinitionMap.put("/user/**", "roles[user]"); 4 5 // 理想中的為多角色分配權限方法 6 filterChainDefinitionMap.put("/behindIndexPage","roles[admin,user]");
使用Shiro自帶的方法,由於是map結構,下面的roles[user]肯定會覆蓋roles[admin],所以使用自帶方法,只能為一個權限分配一個角色。於是搜尋了一下理想中的分配多角色權限的解決方案,方便日后再用。
首先,需要重寫Shiro自帶角色權限過濾器
1 public class RoleFilter extends RolesAuthorizationFilter { 2 @Override 3 public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) 4 throws IOException { 5 6 final Subject subject = getSubject(request, response); 7 final String[] rolesArray = (String[]) mappedValue; 8 9 if (rolesArray == null || rolesArray.length == 0) { 10 // 無指定角色時,無需檢查,允許訪問 11 return true; 12 } 13 14 for (String roleName : rolesArray) { 15 if (subject.hasRole(roleName)) { 16 return true; 17 } 18 } 19 20 return false; 21 } 22 }
然后,只需在Shiro配置類中將剛剛寫的自定義過濾器配置進去即可。
1 @Configuration 2 public class ShiroConfig { 3 @Bean 4 public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { 5 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 6 shiroFilterFactoryBean.setSecurityManager(securityManager); 7 // 存放自定義的filter,這里導入的是:javax.servlet.Filter 8 LinkedHashMap<String, Filter> filtersMap = new LinkedHashMap<>(); 9 // 配置自定義 or角色 認證 10 filtersMap.put("roles", new RoleFilter()); 11 shiroFilterFactoryBean.setFilters(filtersMap); 12 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); 13 filterChainDefinitionMap.put("/index","roles[admin,user]"); 14 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); 15 return shiroFilterFactoryBean; 16 17 } 18 }