Springboot整合Shiro-多权限调用接口问题

  • Post author:
  • Post category:其他




问题

​ 在开发中,我们希望不同的角色权限可以调用同一个API接口,例如/user/**相关API既可以由拥有admin权限的角色调用,也可以由拥有student权限的角色调用,这时我们可能会有2种方案


方案一

filterMap.put("/user/**","roles[admin]");
filterMap.put("/user/**","roles[student]");


方案二

filterMap.put("/user/**","roles[admin,student]");

​ 但实际上,以上方法均不可行,由于shiro的内置过滤器是顺序执行,方案一中的

roles[student]

会覆盖掉前面的

roles[admin]

,导致

admin

权限角色无法调用对应接口;而方案二则会导致两种权限的角色都无法进行调用,翻阅shiro自带的权限过滤器

RolesAuthorizationFilter

源码发现,用户需要拥有roleArray中全部权限才能调用对应接口。



shiro自带的权限过滤器

/**
 * Filter that allows access if the current user has the roles specified by the mapped value, or denies access
 * if the user does not have all of the roles specified.
 *
 * @since 0.9
 */
public class RolesAuthorizationFilter extends AuthorizationFilter {

    //TODO - complete JavaDoc

    @SuppressWarnings({"unchecked"})
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {

        Subject subject = getSubject(request, response);
        String[] rolesArray = (String[]) mappedValue;

        if (rolesArray == null || rolesArray.length == 0) {
            //no roles specified, so nothing to check - allow access.
            return true;
        }
		//需要用户拥有roleArray中全部权限才能调用对应接口(需重写代码)
        Set<String> roles = CollectionUtils.asSet(rolesArray);
        return subject.hasAllRoles(roles);
    }

}



重写权限过滤器的isAccessAllowed

/**
 * 自定义角色权限管理器
 * roles[admin]->roles[admin,student]
 */
public class ShiroRoleFilter extends RolesAuthorizationFilter {

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {

        Subject subject = getSubject(request, response);
        String[] rolesArray = (String[]) mappedValue;

        if (rolesArray == null || rolesArray.length == 0) {
            //no roles specified, so nothing to check - allow access.
            return true;
        }
		//满足任一权限即可
        for(String roleName : rolesArray) {
            if(subject.hasRole(roleName)) {
                return true;
            }
        }
        return false;
    }
}



ShiroConfig配置类部分代码

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(defaultWebSecurityManager);

        Map<String, Filter> filters = bean.getFilters();
        //添加自定义权限过滤器
        filters.put("roles",new ShiroRoleFilter());
        bean.setFilters(filters);

        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/user/**","roles[admin,student]");

        bean.setFilterChainDefinitionMap(filterMap);

        return bean;
    }



版权声明:本文为weixin_47208793原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。