基于RBAC的权限访问系统基础

需要,基于RBAC的权限访问,采用SpringSecurity安全管理框架+SpringBoot+Mybatis数据库持久框架。

数据库设计:

user用户名:ennabled,accountNonExpired,accountNonLocked,CredentialsNonExpired默认为1

基于RBAC的权限访问系统基础

role角色表:

基于RBAC的权限访问系统基础

permission权限表:

基于RBAC的权限访问系统基础

user_role 用户-角色中间表:

基于RBAC的权限访问系统基础

role_permission色色-权限中间表:

基于RBAC的权限访问系统基础

permission表中初始数据,权限名为permTag

基于RBAC的权限访问系统基础

编码实现:

1.pom.xml,引入了jdbc,thymeleaf,security,web,mybatis,devtools,lombox,mysql

<dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-jdbc</artifactId>         </dependency>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-thymeleaf</artifactId>         </dependency>         <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-security</artifactId>             <version>2.3.1.RELEASE</version>         </dependency>           <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>         <dependency>             <groupId>org.mybatis.spring.boot</groupId>             <artifactId>mybatis-spring-boot-starter</artifactId>             <version>2.1.2</version>         </dependency>           <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-devtools</artifactId>             <scope>runtime</scope>             <optional>true</optional>         </dependency>         <dependency>             <groupId>mysql</groupId>             <artifactId>mysql-connector-java</artifactId>             <scope>runtime</scope>         </dependency>         <dependency>             <groupId>org.projectlombok</groupId>             <artifactId>lombok</artifactId>             <optional>true</optional>         </dependency>

2.application.properties

#数据库连接,暂时未使用数据库连接池 spring.datasource.url=jdbc:mysql://localhost:3306/yderp spring.datasource.username=root spring.datasource.password=a61322799 #开发期间不需要缓存模板 spring.thymeleaf.cache=false

3.资源文件,其中main.html为需要权限才能访问的页面

基于RBAC的权限访问系统基础

reg.html

<form action="/reg" method="post">     用户名<input type="text" name="username"/> <br/>     用户名<input type="text" name="realname"/> <br/>     密码 <input type="password" name="password"/><br/>     <input type="submit" value="注册"> </form>

login.html

<!--name值:必须为username password--> <form method="post" action="/login">     用户名:<input type="text" name="username">     密码<input type="text" name="password">     <input type="submit" value="登录"> </form> <!-- MySecurity类中 .failureUrl("/login?error=true")--> <label style="color: red" th:if=${param.error} th:text="账户密码错误,请重新登录"></label> </body>

index.html

<body> this is Main page! <a href="/main">权限页面</a> <a href="/logout">注销</a> </body>

main.html

<body> 本页面需要权限访问 <a href="/logout">注销</a> </body>

4.实体类domain

//角色实现UserDetails接口实现用户的封装 @Data public class User  implements UserDetails {     private int id;     private String username;     private String realname;     private String password;     private LocalDate createDate;     private LocalDateTime lastLoginTime;     //账户是否不可用,数据库为1代表true,0代表false,默认为1     private boolean enabled;     //账户是否未过期     private boolean accountNonExpired;     //账户是否锁定     private boolean accountNonLocked;     //密码是否未过期     private boolean credentialsNonExpired;     //权限集合     private List<GrantedAuthority>  authorities; }   @Data public class Role {     private int id;     private String roleName;     private String roleDesc; }   @Data public class Permission {     private int id;     private String permName;     //权限标志符,authorities集合的值     private String permTag; }

5.数据库查询dao接口

@Mapper @Component public interface UserDao {     //用户名查询用户信息     @Select("select * from user where userName = #{userName}")     public User selectByUserName(String userName);     //用户名查询当前用户的权限信息     @Select("select permission.* FROM" +             "    user  u" +             "    INNER JOIN user_role ON u.id = user_role.uid" +             "    INNER JOIN role_permission on user_role.rid = role_permission.rid" +             "    INNER JOIN permission on role_permission.pid = permission.id" +             "    WHERE u.username = #{userName};")     public List<Permission> findPermissionByUserName(String userName);     //注册用户     @Insert("insert into user values(default,#{user.username}," +             "#{user.realname},#{user.password},now(),now(),default,default,default,default)")     int insert(@Param("user") User user); }

6.UserService

public interface UserService {     public int insert(User user); }   @Service public class UserServiceImpl implements UserService {     @Autowired     private UserDao userDao =null;     @Override     public int insert(User user) {         return userDao.insert(user);     } }

7.MyController注册

@Controller public class MyController {     @Autowired     UserService userService = null;     //用户注册     @RequestMapping("/reg")     @ResponseBody     public String reg(User user){         System.out.println(user);         String pwd = user.getPassword();         //加密,springSecurity现在默认要强制加密         pwd = new BCryptPasswordEncoder().encode(pwd);          user.setPassword(pwd);         int insert = userService.insert(user);         if(insert > 0){             return "注册成功";         }         return "注册失败";      } }

8.springMVC config配置

@Configuration public class MyConfig implements WebMvcConfigurer {    //静态资源URI和位置映射     @Override     public void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("/static/**")                 .addResourceLocations("classpath:/static/");     }     //视图映射     @Override     public void addViewControllers(ViewControllerRegistry registry) {         registry.addViewController("/login").setViewName("login");         registry.addViewController("/").setViewName("index");         registry.addViewController("/403").setViewName("403");         registry.addViewController("/main").setViewName("main");     } }

9.权限不足逻辑跳转

@Configuration public class ErrorPageConfig implements ErrorPageRegistrar  {     @Override     public void registerErrorPages(ErrorPageRegistry registry) {         //权限不足的页面导向         ErrorPage error403 = new ErrorPage(HttpStatus.FORBIDDEN,"/403");         registry.addErrorPages(error403);     } }

10.UserDetailsService接口的实现

@Service public class MyUserDetalisService implements UserDetailsService {     @Autowired     UserDao userDao = null;       @Override     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {         //查询当前用户信息         User user = userDao.selectByUserName(username);         //查询当前用户权限         List<Permission> list = userDao.findPermissionByUserName(username);         List<GrantedAuthority> authorities = new ArrayList<>();         /*         * 将getPermTag()构建一个GrantedAuthority接口实例对象,放于List<GrantedAuthority>中         * */         list.forEach(l ->{             authorities.add(new SimpleGrantedAuthority(l.getPermTag()));         });         //用户信息设置权限集合         user.setAuthorities(authorities);         return user;     } }

11.springSecurity配置,重点

@EnableWebSecurity public class MySecurity extends WebSecurityConfigurerAdapter {     @Autowired     MyUserDetalisService myUserDetalisService = null;       //http安全配置     @Override     protected void configure(HttpSecurity http) throws Exception {         http.authorizeRequests()  //所有请求拦截          .antMatchers("/static/**").permitAll() //放在所有拦截的前面放行不需要拦截的资源          .antMatchers("/login").permitAll()  //放行登录          .antMatchers("/logout").permitAll() //放行注销          .antMatchers("/reg").permitAll()  //放行注册          .antMatchers("/main").hasAnyAuthority("ROLE_PRODUCT_LIST")//此页需要权限          .anyRequest().authenticated() //除上所有拦截需要用户认证              .and()                 .formLogin().loginPage("/login") //forlogin认证                 .failureUrl("/login?error=true")//登陆错误页             .and()                 .csrf().disable(); //关闭csrf校验       }     //认证管理器配置     @Override     protected void configure(AuthenticationManagerBuilder auth) throws Exception {         auth.userDetailsService(myUserDetalisService)                 //查询时需要密码加密后和数据库做比较                 .passwordEncoder(new BCryptPasswordEncoder());     } }

您可能还会对下面的文章感兴趣: