栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot+Shiro配置数据库实现后台管理页面根据角色权限动态生成菜单栏

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot+Shiro配置数据库实现后台管理页面根据角色权限动态生成菜单栏

目录

前言配置数据库动态生成菜单栏

实现步骤

数据库表后台实现shiro配置 总结

参考表数据测试页面效果 前言

SpringBoot+Shiro做后台管理项目配置权限时,普遍的做法是通过配置shiro标签在html页面里面,来判断当前用户是否拥有该权限,来确认是否展示当前菜单,shiro标签类似如下:

add用户

没有权限

权限与判断

这种方式缺点是需要手写所有菜单标签,也要在shiro标签内加上对应的权限标识,在菜单列表比较多的时候,index页面会显得很臃肿,而且自己也容易混淆其中的权限标识。

配置数据库动态生成菜单栏

配置后台权限表,在用户登录通过后,进入index页面时,通过用户的角色id查询出该用户拥有的权限,在使用freemarker或者thymeleaf模板引擎动态地渲染出左侧菜单栏。在需要添加菜单栏时,只需要在数据库中添加数据就可以了。并且所有的权限数据都是在数据库中完成的,不需要再单独地写shiro标签了。

实现步骤 数据库表

1.user表

2.user_role表

3.role表

4.permission表

5.role_permission表

6.menu表

后台实现

    Controller

    @GetMapping("/index")
    public String login(Model model) {
        //获取当前用户名得到菜单
        Subject subject = SecurityUtils.getSubject();
        if(!subject.isAuthenticated()) {
            return "/login";
        }
        //根据当前登录账号来获取当前当前账号所拥有权限的菜单列表
        String username = subject.getPrincipal().toString();
        List menuTree = menuService.findMenuTreeByUsername(username);
        model.addAttribute("menuTree",menuTree);
        return "index";
    }
    

    Service

    public interface MenuService extends IService

    {
    List findMenuTreeByUsername(String username);
    }

    ServiceImpl

    @Service
    public class MenuServiceImpl extends ServiceImpl implements MenuService {
    @Autowired
    private MenuMapper menuMapper;

    @Override
    public List findMenuTreeByUsername(String username) {
        return menuMapper.findMenuTreeByUsername(username);
    }
    

    }

    Mapper

    public interface MenuMapper extends baseMapper

    {

    List findMenuTreeByUsername(@Param(“username”)String username);
    }

    xml

    
        
        
        
        
            
            
            
        
    
    
    
        select pm.id,pm.menu_name,pm.menu_icon,m.id mid,m.menu_name mname,m.menu_url murl
    	from user u
    	inner join user_role ur on u.id=ur.user_id
    	inner join role role on ur.role_id=role.id
    	inner join role_permission rp on role.id=rp.role_id
    	inner join permission p on rp.permission_id=p.id
    	inner join menu m on p.menu_id=m.id
    	inner join menu pm on m.menu_id=pm.id
    	where u.username=#{username}
    
    

    VO对象

    @Data
    public class Menus {
    private Long menuId;
    private String menuName;
    private String menuUrl;
    private String menuIcon;
    private List subMenus;
    }

    index页面使用freemarker渲染菜单列表

    		//此处是通过freemarker模板引擎生成,用thymeleaf的话也是可以的
            

    menuTree <#list menuTree as menus>

  1. ${menus.menuName}
    <#list menus.subMenus as s>
    ${s.menuName}
    < /dl>
shiro配置

    ShiroConfig添加权限标识
    ShiroConfig文件里面,通过查询在数据库里配置的全选标识,给所有的需要权限的资源添加权限标识,同时,通过这种方式,直接省略了在每个接口上面添加@RequiresPermissions(“user:add”)类似的注解。

    @Bean("shiroFilter")       //必须叫这个。
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置securityManager
        bean.setSecurityManager(manager);
        //设置登录页面
        bean.setLoginUrl("/login");
        bean.setSuccessUrl("/index");
        bean.setUnauthorizedUrl("/auth.html");
        //定义过滤器
        linkedHashMap filterChainDefinitionMap = new linkedHashMap<>();
        //配置记住我或认证通过可以访问的地址
        filterChainDefinitionMap.put("/index", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/swagger-ui.html", "anon");
        filterChainDefinitionMap.put("/swagger-resources", "anon");
        filterChainDefinitionMap.put("/swagger-resources/configuration/security", "anon");
        filterChainDefinitionMap.put("/swagger-resources/configuration/ui", "anon");
        filterChainDefinitionMap.put("/api/**", "anon");
        //通过查询在数据库里面的权限标识,循环给自己设定的字段添加标识权限
        List list = permissionMapper.getAll();
        for (Permission permission : list) {
            filterChainDefinitionMap.put(permission.getResource(), "perms["+permission.getSn()+"]");
        }
        //需要登录访问的资源 , 一般将/**放在最下边
        filterChainDefinitionMap.put("/**", "anon");   //    , 不需要认证。
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }
    

    permissionMapper

    public interface PermissionMapper extends baseMapper {
    List getPermissionsByUserName(@Param(“username”)String username);

    List getAll();
    

    }

    Xml

    
        select
    	r.id,
    	r.role_name,
    	r.remake
    	from role r
    	left join user_role ur on ur.role_id=r.id
    	left join user u on u.id=ur.user_id
    	where u.username=#{username}
    
    

    xml

    
        
        
        
        
        
    
    
    
总结

在使用这种方式动态生成菜单栏的话,刚开始没接触过时会觉得难以理解,实际上只要弄清楚了这些表之间的关系,再整理一下实现逻辑,最后发现这种方式还是挺方便的。

参考表数据

menu

permission表

role_permission

role

role_user

user

测试页面效果

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/786227.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号