当前位置:   article > 正文

SpringBoot+Spring Security+Vue实现动态权限菜单方案(附源码)

springsecurity vue 动态权限管
1、前言

在实际开发中,开发任何一套系统,基本都少不了权限管理这一块。这些足以说明权限管理的重要性。其实SpringSecurity去年就学了,一直没有时间整理,用了一年多时间了,给我的印象一直都挺好,实用,安全性高(Security可以对密码进行加密)。而且这一块在实际开发中也的确很重要,所以这里整理了一套基于SpringSecurity的权限管理。

案例代码下面有下载链接。

2、案例技术栈

如果对于SpringSecurity还不了解的话可以先了解一下SpringSecurity安全控件的学习,页面采用的是Bootstrap写的(页面就简单的写了一下,可以根据自己的需求更改),其实后端理解了,前台就是显示作用,大家可以自行更换前台页面显示框架,持久层使用的是Spring-Data-Jpa。

并且对后端持久层和控制器进行了一下小封装,Java持久层和控制器的封装。页面使用的Thymeleaf模板,SpringBoot整合Thymeleaf模板。

数据库设计

1、表关系
8154399896e7bed6ec165520d751a509.png
  • 菜单(TbMenu)=====> 页面上需要显示的所有菜单

  • 角色(SysRole)=====> 角色及角色对应的菜单

  • 用户(SysUser)=====> 用户及用户对应的角色

  • 用户和角色中间表(sys_user_role)====> 用户和角色中间表

2、数据库表结构

菜单表tb_menu

8d14ccbaeeab737b1a39c7be0117a3ad.png

角色及菜单权限表sys_role,其中父节点parent 为null时为角色,不为null时为对应角色的菜单权限。

f169f2b62b021ba8c7c05e1d5b459127.png

用户表sys_user

eb59178902db8818a9922b978d516538.png

用户和角色多对多关系,用户和角色中间表sys_user_role(有Spring-Data-Jpa自动生成)。

130a922205ebfed85a5f32eaf90ea802.png

新建项目

1、新建springboot项目

新建springboot项目,在项目中添加SpringSecurity相关Maven依赖,pom.map文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.     <modelVersion>4.0.0</modelVersion>
  5.     <parent>
  6.         <groupId>org.springframework.boot</groupId>
  7.         <artifactId>spring-boot-starter-parent</artifactId>
  8.         <version>2.2.2.RELEASE</version>
  9.         <relativePath/> <!-- lookup parent from repository -->
  10.     </parent>
  11.     <groupId>com.mcy</groupId>
  12.     <artifactId>springboot-security</artifactId>
  13.     <version>0.0.1-SNAPSHOT</version>
  14.     <name>springboot-security</name>
  15.     <description>Demo project for Spring Boot</description>
  16.  
  17.     <properties>
  18.         <java.version>1.8</java.version>
  19.     </properties>
  20.  
  21.     <dependencies>
  22.         <dependency>
  23.             <groupId>org.springframework.boot</groupId>
  24.             <artifactId>spring-boot-starter-data-jpa</artifactId>
  25.         </dependency>
  26.         <dependency>
  27.             <groupId>org.springframework.boot</groupId>
  28.             <artifactId>spring-boot-starter-security</artifactId>
  29.         </dependency>
  30.         <dependency>
  31.             <groupId>org.springframework.boot</groupId>
  32.             <artifactId>spring-boot-starter-thymeleaf</artifactId>
  33.         </dependency>
  34.         <dependency>
  35.             <groupId>org.springframework.boot</groupId>
  36.             <artifactId>spring-boot-starter-web</artifactId>
  37.         </dependency>
  38.  
  39.         <dependency>
  40.             <groupId>mysql</groupId>
  41.             <artifactId>mysql-connector-java</artifactId>
  42.             <scope>runtime</scope>
  43.         </dependency>
  44.         <dependency>
  45.             <groupId>org.springframework.boot</groupId>
  46.             <artifactId>spring-boot-starter-test</artifactId>
  47.             <scope>test</scope>
  48.             <exclusions>
  49.                 <exclusion>
  50.                     <groupId>org.junit.vintage</groupId>
  51.                     <artifactId>junit-vintage-engine</artifactId>
  52.                 </exclusion>
  53.             </exclusions>
  54.         </dependency>
  55.         <dependency>
  56.             <groupId>org.springframework.security</groupId>
  57.             <artifactId>spring-security-test</artifactId>
  58.             <scope>test</scope>
  59.         </dependency>
  60.         <dependency>
  61.             <groupId>org.thymeleaf.extras</groupId>
  62.             <artifactId>thymeleaf-extras-springsecurity5</artifactId>
  63.         </dependency>
  64.         <dependency>
  65.             <groupId>org.springframework.boot</groupId>
  66.             <artifactId>spring-boot-devtools</artifactId>
  67.             <scope>runtime</scope>
  68.             <optional>true</optional>
  69.         </dependency>
  70.         <dependency>
  71.             <groupId>org.webjars.bower</groupId>
  72.             <artifactId>bootstrap-select</artifactId>
  73.             <version>2.0.0-beta1</version>
  74.         </dependency>
  75.         <dependency>
  76.             <groupId>org.webjars</groupId>
  77.             <artifactId>bootbox</artifactId>
  78.             <version>4.4.0</version>
  79.         </dependency>
  80.     </dependencies>
  81.  
  82.     <build>
  83.         <plugins>
  84.             <plugin>
  85.                 <groupId>org.springframework.boot</groupId>
  86.                 <artifactId>spring-boot-maven-plugin</artifactId>
  87.             </plugin>
  88.         </plugins>
  89.     </build>
  90.  
  91. </project>
2、项目结构
1a165165f2caee077e1b72972442bc96.png

编写代码

1、编写实体类

菜单表实体类TbMenu,Spring-Data-Jpa可以根据实体类去数据库新建或更新对应的表结构,详情可以访问Spring-Data-Jpa入门:

https://blog.csdn.net/qq_40205116/article/details/103039936

  1. import com.fasterxml.jackson.annotation.JsonIgnore;
  2. import com.mcy.springbootsecurity.custom.BaseEntity;
  3. import org.springframework.data.annotation.CreatedBy;
  4.  
  5. import javax.persistence.*;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8.  
  9. /**
  10.  * 菜单表
  11.  * @author
  12.  *
  13.  */
  14. @Entity
  15. public class TbMenu extends BaseEntity<Integer> {
  16.  private String name;
  17.  private String url;
  18.  private Integer idx;
  19.  @JsonIgnore
  20.  private TbMenu parent;
  21.  @JsonIgnore
  22.  private List<TbMenu> children=new ArrayList<>();
  23.  
  24.  @Column(unique=true)
  25.  public String getName() {
  26.   return name;
  27.  }
  28.  
  29.  public void setName(String name) {
  30.   this.name = name;
  31.  }
  32.  
  33.  public String getUrl() {
  34.   return url;
  35.  }
  36.  
  37.  public void setUrl(String url) {
  38.   this.url = url;
  39.  }
  40.  
  41.  public Integer getIdx() {
  42.   return idx;
  43.  }
  44.  
  45.  public void setIdx(Integer idx) {
  46.   this.idx = idx;
  47.  }
  48.  
  49.  @ManyToOne
  50.  @CreatedBy
  51.  public TbMenu getParent() {
  52.   return parent;
  53.  }
  54.  
  55.  public void setParent(TbMenu parent) {
  56.   this.parent = parent;
  57.  }
  58.  
  59.  @OneToMany(cascade=CascadeType.ALL,mappedBy="parent")
  60.  @OrderBy(value="idx")
  61.  public List<TbMenu> getChildren() {
  62.   return children;
  63.  }
  64.  
  65.  public void setChildren(List<TbMenu> children) {
  66.   this.children = children;
  67.  }
  68.  
  69.  public TbMenu(Integer id) {
  70.   super(id);
  71.  }
  72.  
  73.  public TbMenu(){
  74.   super();
  75.  }
  76.  
  77.  public TbMenu(String name, String url, Integer idx, TbMenu parent, List<TbMenu> children) {
  78.   this.name = name;
  79.   this.url = url;
  80.   this.idx = idx;
  81.   this.parent = parent;
  82.   this.children = children;
  83.  }
  84.  
  85.  public TbMenu(Integer integer, String name, String url, Integer idx, TbMenu parent, List<TbMenu> children) {
  86.   super(integer);
  87.   this.name = name;
  88.   this.url = url;
  89.   this.idx = idx;
  90.   this.parent = parent;
  91.   this.children = children;
  92.  }
  93.  
  94.  @Transient
  95.  public Integer getParentId() {
  96.   return parent==null?null:parent.getId();
  97.  }
  98. }

表新建好了,下面就是实现增删改查就可以了,实现效果如下。

8e2707e1245a79aef62cdcb9012545e5.png

新增和修改菜单。

c4d5e13835a824e34833e1b18e46fa96.png

对于Bootstrap的树形表格,可以移步到:BootStrap-bable-treegrid树形表格的使用。

https://blog.csdn.net/qq_40205116/article/details/103740104

菜单管理实现了,下一步就是实现角色及角色对应的权限管理了。

角色及权限表SysRole,parent 为null时为角色,不为null时为权限。

  1. package com.mcy.springbootsecurity.entity;
  2.  
  3. import com.fasterxml.jackson.annotation.JsonIgnore;
  4. import com.mcy.springbootsecurity.custom.BaseEntity;
  5. import org.springframework.data.annotation.CreatedBy;
  6. import javax.persistence.*;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9.  
  10. @Entity
  11. /***
  12.  * 角色及角色对应的菜单权限
  13.  * @author
  14.  *parent 为null时为角色,不为null时为权限
  15.  */
  16. public class SysRole extends BaseEntity<Integer> {
  17.  private String name; //名称
  18.  private String code; //代码
  19.  @JsonIgnore
  20.  private SysRole parent;
  21.  private Integer idx; //排序
  22.  @JsonIgnore
  23.  private List<SysRole> children = new ArrayList<>();
  24.  
  25.  @Column(length=20)
  26.  public String getName() {
  27.   return name;
  28.  }
  29.  
  30.  public void setName(String name) {
  31.   this.name = name;
  32.  }
  33.  
  34.  public String getCode() {
  35.   return code;
  36.  }
  37.  
  38.  public void setCode(String code) {
  39.   this.code = code;
  40.  }
  41.  
  42.  @ManyToOne
  43.  @CreatedBy
  44.  public SysRole getParent() {
  45.   return parent;
  46.  }
  47.  
  48.  public void setParent(SysRole parent) {
  49.   this.parent = parent;
  50.  }
  51.  
  52.  @OneToMany(cascade=CascadeType.ALL,mappedBy="parent")
  53.  public List<SysRole> getChildren() {
  54.   return children;
  55.  }
  56.  
  57.  public void setChildren(List<SysRole> children) {
  58.   this.children = children;
  59.  }
  60.  
  61.  //获取父节点id
  62.  @Transient
  63.  public Integer getParentId() {
  64.   return parent==null?null:parent.getId();
  65.  }
  66.  
  67.  public Integer getIdx() {
  68.   return idx;
  69.  }
  70.  
  71.  public void setIdx(Integer idx) {
  72.   this.idx = idx;
  73.  }
  74.  
  75.  public SysRole(String name, String code, SysRole parent, Integer idx, List<SysRole> children) {
  76.   this.name = name;
  77.   this.code = code;
  78.   this.parent = parent;
  79.   this.idx = idx;
  80.   this.children = children;
  81.  }
  82.  
  83.  public SysRole(Integer id, String name, String code, SysRole parent, Integer idx, List<SysRole> children) {
  84.   super(id);
  85.   this.name = name;
  86.   this.code = code;
  87.   this.parent = parent;
  88.   this.idx = idx;
  89.   this.children = children;
  90.  }
  91.  
  92.  public SysRole(Integer id) {
  93.   super(id);
  94.  }
  95.  
  96.  public SysRole(){}
  97. }

首先需要实现角色管理,之后在角色中添加对应的菜单权限。

实现效果(也可以和菜单管理一样,用树形表格展示,根据个人需求。这里用的是树形菜单展示的)。

92f93ea1cefd87c71fcf34aff3faa6c6.png

给角色分配权限。

71b42becf71d25c2947417c0e6e2ffad.png

最后实现的就是用户管理了,只需要对添加的用户分配对应的角色就可以了,用户登录时,显示角色对应的权限。

用户表SysUser,继承的BaseEntity类中就一个ID字段。

  1. import com.fasterxml.jackson.annotation.JsonIgnore;
  2. import com.mcy.springbootsecurity.custom.BaseEntity;
  3.  
  4. import javax.persistence.*;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7.  
  8. /**
  9.  * 用户表
  10.  */
  11. @Entity
  12. public class SysUser extends BaseEntity<Integer> {
  13.  private String username; //账号
  14.  private String password; //密码
  15.  private String name;  //姓名
  16.  private String address;  //地址
  17.  
  18.  @JsonIgnore
  19.  private List<SysRole> roles=new ArrayList<>(); //角色
  20.  
  21.  @Column(length=20,unique=true)
  22.  public String getUsername() {
  23.   return username;
  24.  }
  25.  public void setUsername(String username) {
  26.   this.username = username;
  27.  }
  28.  
  29.  @Column(length=100)
  30.  public String getPassword() {
  31.   return password;
  32.  }
  33.  public void setPassword(String password) {
  34.   this.password = password;
  35.  }
  36.  
  37.  @Column(length=20)
  38.  public String getName() {
  39.   return name;
  40.  }
  41.  public void setName(String name) {
  42.   this.name = name;
  43.  }
  44.  
  45.  @ManyToMany(cascade=CascadeType.REFRESH,fetch=FetchType.EAGER)
  46.  @JoinTable(name="sys_user_role",joinColumns=@JoinColumn(name="user_id"),inverseJoinColumns=@JoinColumn(name="role_id"))
  47.  public List<SysRole> getRoles() {
  48.   return roles;
  49.  }
  50.  public void setRoles(List<SysRole> roles) {
  51.   this.roles = roles;
  52.  }
  53.  
  54.  public String getAddress() {
  55.   return address;
  56.  }
  57.  
  58.  public void setAddress(String address) {
  59.   this.address = address;
  60.  }
  61.  
  62.  //角色名称
  63.  @Transient
  64.  public String getRoleNames() {
  65.   String str="";
  66.   for (SysRole role : getRoles()) {
  67.    str+=role.getName()+",";
  68.   }
  69.   if(str.length()>0) {
  70.    str=str.substring(0, str.length()-1);
  71.   }
  72.   return str;
  73.  }
  74.  
  75.  //角色代码
  76.  @Transient
  77.  public String getRoleCodes() {
  78.   String str="";
  79.   for (SysRole role : getRoles()) {
  80.    str+=role.getCode()+",";
  81.   }
  82.   if(str.indexOf(",")>0) {
  83.    str=str.substring(0,str.length()-1);
  84.   }
  85.   return str;
  86.  }
  87.  
  88. }

用户管理就基本的数据表格,效果如图。

7bea4c5313f3a978c98a45995a0b3a01.png
2、Security配置文件

Security相关配置文件,下面两个文件如果看不懂,可以访问SpringSecurity安全控件的学习中有详细讲解。

https://blog.csdn.net/qq_40205116/article/details/103439326

  1. package com.mcy.springbootsecurity.security;
  2.  
  3. import com.mcy.springbootsecurity.service.SysUserService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  7. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  8. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  9. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  10.  
  11. @Configuration
  12. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  13.  
  14.     @Autowired
  15.     private SysUserService userService;
  16.  
  17.     /**
  18.      * 用户认证操作
  19.      * @param auth
  20.      * @throws Exception
  21.      */
  22.     @Override
  23.     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  24.         //添加用户,并给予权限
  25.         auth.inMemoryAuthentication().withUser("aaa").password("{noop}1234").roles("DIY");
  26.         //设置认证方式
  27.         auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
  28.     }
  29.  
  30.     /**
  31.      * 用户授权操作
  32.      * @param http
  33.      * @throws Exception
  34.      */
  35.     @Override
  36.     protected void configure(HttpSecurity http) throws Exception {
  37.         http.csrf().disable();    //安全器令牌
  38.         http.formLogin()
  39.                 //登录请求被拦截
  40.                 .loginPage("/login").permitAll()
  41.                 //设置默认登录成功跳转页面
  42.                 .successForwardUrl("/main")
  43.                 .failureUrl("/login?error");   //登录失败的页面
  44.         http.authorizeRequests().antMatchers("/static/**""/assets/**").permitAll();    //文件下的所有都能访问
  45.         http.authorizeRequests().antMatchers("/webjars/**").permitAll();
  46.         http.logout().logoutUrl("/logout").permitAll();     //退出
  47.         http.authorizeRequests().anyRequest().authenticated();    //除此之外的都必须通过请求验证才能访问
  48.     }
  49. }

获取登录者相关信息,工具类。

  1. import com.mcy.springbootsecurity.entity.SysUser;
  2. import com.mcy.springbootsecurity.service.SysUserService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.security.core.GrantedAuthority;
  5. import org.springframework.security.core.context.SecurityContextHolder;
  6. import org.springframework.security.core.userdetails.UserDetails;
  7. import org.springframework.stereotype.Component;
  8.  
  9. import java.util.ArrayList;
  10. import java.util.List;
  11.  
  12. //创建会话,获取当前登录对象
  13. @Component
  14. public class UserUtils {
  15.  @Autowired
  16.  private SysUserService userService;
  17.  
  18.  /**
  19.   * 获取当前登录者的信息
  20.   * @return 当前者信息
  21.   */
  22.  public SysUser getUser() {
  23.   //获取当前用户的用户名
  24.   String username = SecurityContextHolder.getContext().getAuthentication().getName();
  25.   SysUser user = userService.findByUsername(username);
  26.   return user;
  27.  }
  28.  
  29.  /**
  30.   * 判断此用户中是否包含roleName菜单权限
  31.   * @param roleName
  32.   * @return
  33.   */
  34.  public Boolean hasRole(String roleName) {
  35.   //获取UserDetails类,
  36.   UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
  37.   List<String> roleCodes=new ArrayList<>();
  38.   for (GrantedAuthority authority : userDetails.getAuthorities()) {
  39.    //getAuthority()返回用户对应的菜单权限
  40.    roleCodes.add(authority.getAuthority());
  41.   }
  42.   return roleCodes.contains(roleName);
  43.  }
  44. }
3、动态权限菜单加载相关方法

用户表的SysUserService需要实现UserDetailsService接口,因为在SpringSecurity中配置的相关参数需要是UserDetailsService类的数据。

重写UserDetailsService接口中的loadUserByUsername方法,通过该方法查询对应的用户,返回对象UserDetails是SpringSecurity的一个核心接口。其中定义了一些可以获取用户名,密码,权限等与认证相关信息的方法。

重写的loadUserByUsername方法。

  1. @Override
  2. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  3.     //调用持久层接口findByUsername方法查询用户。
  4.     SysUser user = userRepository.findByUsername(username);
  5.     if(user == null){
  6.         throw new UsernameNotFoundException("用户名不存在");
  7.     }
  8.     //创建List集合,用来保存用户菜单权限,GrantedAuthority对象代表赋予当前用户的权限
  9.     List<GrantedAuthority> authorities = new ArrayList<>();
  10.     //获得当前用户角色集合
  11.     List<SysRole> roles = user.getRoles();
  12.     List<SysRole> haveRoles=new ArrayList<>();
  13.     for (SysRole role : roles) {
  14.         haveRoles.add(role);
  15.         List<SysRole> children = roleService.findByParent(role);
  16.         children.removeAll(haveRoles);
  17.         haveRoles.addAll(children);
  18.     }
  19.     for(SysRole role: haveRoles){
  20.         //将关联对象role的name属性保存为用户的认证权限
  21.         authorities.add(new SimpleGrantedAuthority(role.getName()));
  22.     }
  23.     //此处返回的是org.springframework.security.core.userdetails.User类,该类是SpringSecurity内部的实现
  24.     //org.springframework.security.core.userdetails.User类实现了UserDetails接口
  25.     return new User(user.getUsername(), user.getPassword(), authorities);
  26. }

所有功能实现了,最后就是根据角色去显示对应的菜单了。

TbMenuService类中的findAuditMenu方法,查询当前用户所拥有的权限菜单。

  1. /**
  2.  * 获取用户所拥有的权限对应的菜单项
  3.  * @return
  4.  */
  5. public List<TbMenu> findAuditMenu() {
  6.     List<TbMenu> menus;
  7.     //判断是否是后门用户
  8.     if(userUtils.hasRole("ROLE_DIY")){
  9.         //查询所有菜单,子菜单可以通过父级菜单的映射得到
  10.         menus = menuRepository.findByParentIsNullOrderByIdx();
  11.     }else{
  12.         //获取此用户对应的菜单权限
  13.         menus = auditMenu(menuRepository.findByParentIsNullOrderByIdx());
  14.     }
  15.     return menus;
  16. }
  17.  
  18. //根据用户的菜单权限对菜单进行过滤
  19. private List<TbMenu> auditMenu(List<TbMenu> menus) {
  20.     List<TbMenu> list = new ArrayList<>();
  21.     for(TbMenu menu: menus){
  22.         String name = menu.getName();
  23.         //判断此用户是否有此菜单权限
  24.         if(userUtils.hasRole(name)){
  25.             list.add(menu);
  26.             //递归判断子菜单
  27.             if(menu.getChildren() != null && !menu.getChildren().isEmpty()) {
  28.                 menu.setChildren(auditMenu(menu.getChildren()));
  29.             }
  30.         }
  31.     }
  32.     return list;
  33. }

在UserUtils工具类中的hasRole方法,判断此用户中是否包含roleName菜单权限。

  1. public Boolean hasRole(String roleName) {
  2.  //获取UserDetails类,
  3.  UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
  4.  List<String> roleCodes=new ArrayList<>();
  5.  for (GrantedAuthority authority : userDetails.getAuthorities()) {
  6.   //getAuthority()返回用户对应的菜单权限
  7.   roleCodes.add(authority.getAuthority());
  8.  }
  9.  return roleCodes.contains(roleName);
  10. }

之后在控制器中返回用户对应的菜单权限,之后在前台页面遍历就可以了。

  1. @RequestMapping(value = "/main")
  2. public String main(ModelMap map){
  3.     //加载菜单
  4.     List<TbMenu> menus = menuService.findAuditMenu();
  5.     map.put("menus", menus);
  6.     if (menus.isEmpty()) {
  7.         return "main/main";
  8.     }
  9.     return "main/main1";
  10. }
4、首页菜单遍历

首页菜单遍历,这里使用的是LayUI菜单,如果其他框架可以自行根据页面标签规律遍历,因为页面使用的是Thymeleaf模板,不是JSP,使用遍历菜单时不是采用的EL表达式,而是使用的Thymeleaf自带的标签表达式。

  1. <div id="main">
  2.     <div id="main_nav">
  3.         <div class="panel-group" id="accordion" style="margin-bottom: 0;">
  4.             <div th:each="menu, menuStat: ${menus}" th:if="${menu.children.size() != 0 && menu.children != null}" class="panel panel-default">
  5.                 <div class="panel-heading">
  6.                     <h4 class="panel-title">
  7.                         <p data-toggle="collapse" data-parent="#accordion" th:href="|#collapseOne${menuStat.index}|">
  8.                             <span th:text="${menu.name}">系统设置</span><span class="caret"></span>
  9.                         </p>
  10.                     </h4>
  11.                 </div>
  12.                 <div th:if="${menuStat.first}" th:id="|collapseOne${menuStat.index}|" class="panel-collapse collapse collapse in">
  13.                     <div class="panel-body">
  14.                         <p th:each="subMenu:${menu.children}" th:src="${subMenu.url}" th:text="${subMenu.name}">菜单管理</p>
  15.                     </div>
  16.                 </div>
  17.                 <div th:if="${!menuStat.first}" th:id="|collapseOne${menuStat.index}|" class="panel-collapse collapse collapse">
  18.                     <div class="panel-body">
  19.                         <p th:each="subMenu:${menu.children}" th:src="${subMenu.url}" th:text="${subMenu.name}">菜单管理</p>
  20.                     </div>
  21.                 </div>
  22.             </div>
  23.         </div>
  24.         <div id="nav_p">
  25.             <p th:each="menu:${menus}" th:if="${menu.children.size() == 0}" th:src="${menu.url}" th:text="${menu.name}">成绩管理</p>
  26.         </div>
  27.     </div>
  28.     <div id="main_home">
  29.         首页内容
  30.     </div>
  31. </div>

测试应用

1、对应效果展示

用户数据及对应的角色

b1538dc9e387803931ab8ab52cfb102c.png

管理员对应的菜单权限。

effe151d7c9c014c02ef8c5c8a44a073.png

用户角色对应的菜单权限。

3e652afd87ce8b29f91d73aea4126a4c.png

测试用户角色对应的菜单权限。

5fac9a7c8c27168fad80b3705aa4c9f6.png
2、测试应用

用户名为admin1有管理员角色的用户登录,菜单显示。

053e47e607be66a35d2a3d806e27c98f.png

用户名为admin2有用户角色的用户登录,菜单显示。

e25fa3ad8862b9a4dc244c8a02072c95.png

用户名为admin3有测试用户角色的用户登录,菜单显示。

dd3b307c89d232f33c8202b74381e7fc.png
3、案例代码下载

下载地址:https://github.com/machaoyin/SpringBoot-Security

来源:blog.csdn.net/qq_40205116/article/details/103739978

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/53924
推荐阅读
相关标签
  

闽ICP备14008679号