01-shiro权限系统-项目搭建

权限系统的必要性

权限管理系统是众多大型项目的标配。可以说,如果没有权限系统的支持,很多功能都会变得难以实现。

OA 系统为例,各个部门要有不同的操作界面、资料。比如,人事部只要公司的人员资料录入,销售部只要公司的销售资料录入。这时候,如果没有限制各个部门的权限,系统就很容易出现:人员误操作、系统的学习成本高昂等情况。

总结上述例子,权限系统有以下优点:

  1. 安全性:避免误操作、人为破坏、数据泄露等;
  2. 数据隔离:不同权限能看到、操作不同的数据;
  3. 明确职责:可以分配:运营、客服等不同角色,领导及下属等不同等级;

权限系统分类

用户—权限

适合人员少,功能固定,或者特别简单的系统

例如,Mysql中用户对数据库的操作权限

RBAC(用户->角色->权限)

用户->角色->权限,都适用。整体关系,如下图:

01-shiro权限系统-项目搭建_第1张图片
用户角色.png

文章中,我们用 shiro 来实现 RBAC 权限系统,下面我们先搭建一个基本的业务系统。

业务系统

创建数据表

shiro 是一个 RBAC 型的权限系统,适用于:用户->角色->权限。所以,我们需要新建的数据表有:

  1. 用户表,包括:id、用户名、密码;
  2. 角色表,包括:id、英文名、中文名;
  3. 权限表,包括:id、权限标识、对应url;
  4. 用户、角色关联表,包括:用户id、角色id;
  5. 角色、权限关联表,包括:角色id、权限id;

SQL脚本如下:
init.sql

实体类

根据数据库中的表,我们可以得出下面 3 个实体类,他们的关系:用户 ——> 角色 ——> 权限,如 UML 图:

01-shiro权限系统-项目搭建_第2张图片
实体类及关系.PNG

他们的代码,即下列所示:

  1. 用户对象
    import java.io.Serializable;
    import java.util.HashSet;
    import java.util.Set;
    
    public class User implements Serializable {
    
        // 唯一编号
        private Integer uid;
    
        // 用户名
        private String username;
    
        // 密码
        private String password;
    
        // 角色列表
        private Set roles = new HashSet<>();
    
    }
  1. 角色对象
    import java.io.Serializable;
    import java.util.HashSet;
    import java.util.Set;

    public class Role implements Serializable {
    
        // 唯一编号
        private Integer rid;
    
        // 角色名称
        private String rname;
    
        // 角色包含的权限集合
        private Set permissions = new HashSet<>();
        
        /** 省略 getter 和 setter 方法 **/
    }
  1. 权限对象
    import java.io.Serializable;

    public class Permission implements Serializable {
        // 唯一编号
        private Integer pid;
    
        // 权限标识
        private String name;
    
        // 权限对应的url
        private String url;
    
        /** 省略 getter 和 setter 方法 **/
    }

数据库查询代码

程序使用 SpringBoot + Mybatis,这里我们只关注 XML 中的主要 SQL,其它请参考下载项目代码:

    
    
        
        
        
        
        
        
            
            
            
            
            
                
                
                
            
        
    

    
    

控制层

项目使用 SpringMVC 提供“视图及数据交互”接口,属于主流技术,这里不再详细说明,直接贴出整个 Controller :

    import com.mmall.demo2.model.User;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.subject.Subject;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    public class TestController {
    
        /**
         * 登陆页面
         * @return
         */
        @RequestMapping("/login")
        public String login() {
            return "login";
        }
    
        /**
         * 主页
         * @param model
         * @return
         */
        @RequestMapping("/index")
        public String index(Model model) {
            Subject subject = SecurityUtils.getSubject();
            User user = (User) subject.getPrincipal();
    
            model.addAttribute("user", user);
            return "index";
        }
    
        /**
         * 用户登陆逻辑
         * @param username
         * @param password
         * @return
         */
        @RequestMapping("/loginUser")
        public String loginUser(@RequestParam("username") String username,
                                @RequestParam("password") String password) {
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            Subject subject = SecurityUtils.getSubject();
            try {
                subject.login(token);
                return "redirect:/index";
            } catch (Exception e) {
                return "login";
            }
        }
    
        /**
         * 用户注销逻辑
         * @return
         */
        @RequestMapping("/logout")
        public String logout() {
            Subject subject = SecurityUtils.getSubject();
            if (subject != null) {
                subject.logout();
            }
            return "login";
        }
    
        /**
         * 无权限访问页面
         * @return
         */
        @RequestMapping("unauthorized")
        public String unauthorized() {
            return "unauthorized";
        }
    
        /**
         * 管理员专属页面,只有管理员角色可以访问
         * @return
         */
        @ResponseBody
        @RequestMapping("/admin")
        public String admin() {
            return "admin";
        }
    
        /**
         * 拥有“修改”权限,才能访问该接口
         * @return
         */
        @ResponseBody
        @RequestMapping("/edit")
        public String edit() {
            return "edit success";
        }
    
        /**
         * 拥有“查询”权限,才能访问该接口
         * @return
         */
        @ResponseBody
        @RequestMapping("/query")
        public String query() {
            return "query success";
        }
    
    }

写在最后

我们已经完成了权限系统的基础搭建。下篇文章,我们就开始把 Shiro 整合到项目里面。这里附上项目源码:

shiro单服务器版地址

你可能感兴趣的:(01-shiro权限系统-项目搭建)