实习小结---权限管理(RBAC)

Posted Mipha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实习小结---权限管理(RBAC)相关的知识,希望对你有一定的参考价值。

  这一周,大多数时间 用来做需求分析,细化每个页面需要实现的功能。由于这个项目需要四种身份登录查看,分别是学生,老师,领导,管理员。每个身份登入系统显示得页面都不相同,四个角色分析完成后,统计了一下页面,居然达到40多个。。。数据库中表一共只有六七个,存在多个页面之间数据重复显示得现象。这时候就需要加入权限管理,一个页面,每个人登录进来后只要显示得页面不同即可。

  设计理念参照了RBAC,这里不多详细介绍。核心内容主要为加入了角色的概念,赋予角色一定的权限,再将角色赋给用户,易于扩展和维护。

表结构图

 表之前的关联如上图:

下面列出每个表的结构和数据

用户表 user

角色表 role

用户角色关系表 user_role

权限表 power

表中的pid为该权限对应的上一级的权限id

角色权限关系表 role_power

下面为测试权限管理做的demo

注:本项目只能实现二级权限,三级权限以及以下本文中的方法不再适用

展示效果

程序的展示效果是,若登录者是老师时,显示得导航栏数据为

学生登录显示得内容为

项目代码

本项目沿用了之前搭建的SSM框架,配置文件的部分就不再赘述

项目的目录结构如下

实体类

Power.java

package com.sysystem.model.entity;

public class Power {

    private Integer power_id;
    private String power_name;
    private Integer pid;
    private Power prwer;

    public Power getPrwer() {
        return prwer;
    }

    public void setPrwer(Power prwer) {
        this.prwer = prwer;
    }

    public Integer getPid() {
        return pid;
    }

    public void setPid(Integer pid) {
        this.pid = pid;
    }

    public Integer getPower_id() {
        return power_id;
    }

    public void setPower_id(Integer power_id) {
        this.power_id = power_id;
    }

    public String getPower_name() {
        return power_name;
    }

    public void setPower_name(String power_name) {
        this.power_name = power_name;
    }

    public Power(Integer power_id, String power_name) {
        super();
        this.power_id = power_id;
        this.power_name = power_name;
    }

    public Power() {

    }

    public Power(Integer power_id, String power_name, Integer pid, Power prwer) {
        super();
        this.power_id = power_id;
        this.power_name = power_name;
        this.pid = pid;
        this.prwer = prwer;
    }

}
View Code

Role.java

package com.sysystem.model.entity;

public class Role {
    private Integer role_id;
    private String role_name;
    private String remark;

    public Integer getRole_id() {
        return role_id;
    }

    public void setRole_id(Integer role_id) {
        this.role_id = role_id;
    }

    public String getRole_name() {
        return role_name;
    }

    public void setRole_name(String role_name) {
        this.role_name = role_name;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public Role(Integer role_id, String role_name, String remark) {
        super();
        this.role_id = role_id;
        this.role_name = role_name;
        this.remark = remark;
    }

    public Role(String role_name, String remark) {
        super();
        this.role_name = role_name;
        this.remark = remark;
    }

}
View Code

RoleAndPower.java

package com.sysystem.model.entity;

public class RoleAndPower {
    private Role role;
    private Power power;

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    public Power getPower() {
        return power;
    }

    public void setPower(Power power) {
        this.power = power;
    }

    public RoleAndPower(Role role, Power power) {
        super();
        this.role = role;
        this.power = power;
    }

    public RoleAndPower() {
    }

}
View Code

User.java

package com.sysystem.model.entity;

import java.util.Set;

public class User {
    private Integer user_id;
    private String user_name;
    private String user_pass;
    private Set<UserAndRole> userRoles;

    public User(Integer user_id, String user_name, String user_pass,
            Set<UserAndRole> userRoles) {
        super();
        this.user_id = user_id;
        this.user_name = user_name;
        this.user_pass = user_pass;
        this.userRoles = userRoles;
    }

    public User() {
        super();
        // TODO Auto-generated constructor stub
    }

    public User(String user_name, String user_pass) {
        super();
        this.user_name = user_name;
        this.user_pass = user_pass;
    }

    public User(String user_name, String user_pass, Set<UserAndRole> userRoles) {
        super();
        this.user_name = user_name;
        this.user_pass = user_pass;
        this.userRoles = userRoles;
    }

    public Set<UserAndRole> getUserRoles() {
        return userRoles;
    }

    public void setUserRoles(Set<UserAndRole> userRoles) {
        this.userRoles = userRoles;
    }

    public Integer getUser_id() {
        return user_id;
    }

    public void setUser_id(Integer user_id) {
        this.user_id = user_id;
    }

    public String getUser_name() {
        return user_name;
    }

    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }

    public String getUser_pass() {
        return user_pass;
    }

    public void setUser_pass(String user_pass) {
        this.user_pass = user_pass;
    }

    public User(Integer user_id, String user_name, String user_pass) {
        super();
        this.user_id = user_id;
        this.user_name = user_name;
        this.user_pass = user_pass;
    }

    

}
View Code

UserAndRole.java

package com.sysystem.model.entity;

public class UserAndRole {
    private User user;
    private Role role;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    public UserAndRole(User user, Role role) {
        this.user = user;
        this.role = role;
    }

    public UserAndRole() {
        
    }
}
View Code

dao层

IPowerDao.java

package com.sysystem.model.dao;

import java.util.List;
import java.util.Map;

import com.sysystem.model.entity.Power;
import com.sysystem.model.entity.User;

public interface IPowerDao {

    // 根据姓名查询用户
    List<User> getUserbyName(String name);
    
    // 根据姓名获取该用户的所有一级标题
    List<Power> getfirstPow(String name);

    // 根据一级标题获取子标题
    List<Power> getChildbyName(Map<String, Object> map);
    
    // 根据姓名获得所有二级权限
    List<Power> getSecPow(String name);

}

IPowerDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.sysystem.model.dao.IPowerDao">
    <!-- 根据姓名获取用户 -->
    <select id="getUserbyName" parameterType="java.lang.String"
        resultType="User">
        select * from user where user_name = #{name}
    </select>

    <!-- 根据姓名获取该用户的一级权限 -->
    <select id="getfirstPow" parameterType="java.lang.String"
        resultType="Power">
        SELECT
            p.power_id,
            p.power_name,
            p.pid
        FROM
            power p,
            role_power rp,
            USER u,
            role r,
            user_role ur
        WHERE
            p.power_id = rp.power_id
        AND r.role_id = rp.role_id
        AND u.user_id = ur.user_id
        AND r.role_id = ur.role_id
        AND u.user_name = #{name}
        AND p.pid IS NULL
    </select>
    
    <!-- 根据姓名获取该用户的二级权限 -->
    <select id="getSecPow" parameterType="java.lang.String"  resultType="Power">
        SELECT
            p.power_id,
            p.power_name,
            p.pid
        FROM
            power p,
            role_power rp,
            USER u,
            role r,
            user_role ur
        WHERE
            p.power_id = rp.power_id
        AND r.role_id = rp.role_id
        AND u.user_id = ur.user_id
        AND r.role_id = ur.role_id
        AND u.user_name = #{name}
        AND p.pid IS NOT NULL
    </select>

    <!-- 获得指定具体人名的二级权限-->
    <select id="getChildbyName" parameterType="java.util.Map" resultType="Power">
        SELECT
            p.power_id,p.power_name
        FROM
            user u,
            role r,
            user_role ru,
            power p,
            role_power rp
        WHERE
            u.user_id = ru.user_id
        AND ru.role_id = r.role_id
        AND p.power_id = rp.power_id
        AND r.role_id = rp.role_id
        AND u.user_name = #{name}
        and p.pid = #{pid}
    </select>
    
</mapper>

service层

service层中的方法和dao层中的一样,调用了dao层中的方法

controller

PowerController.java

package com.sysystem.controller;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.sysystem.model.entity.Power;
import com.sysystem.model.entity.User;
import com.sysystem.model.service.IPowerService;

@Controller
@RequestMapping("/power")
public class PowerController extends BaseController {
    @Resource
    private IPowerService powerService;

    /**
     * 进行登录验证
     * 
     */
    @RequestMapping("/login")
    public String login(HttpServletRequest request,
            HttpServletResponse response, User u) throws Exception {
        String error = "";
        // 根据姓名获得用户集合判断用户是否存在
        List<User> list = powerService.getUserbyName(u.getUser_name());
        if (list.size() == 0) {
            error = "用户不存在";
            request.setAttribute("error", error);
            return "login";
            // 根据账号密码判断是否输入正确
        } else if (!(u.getUser_name().equals(list.get(0).getUser_name()) && u
                .getUser_pass().equals(list.get(0).getUser_pass()))) {
            error = "密码错误";
            request.setAttribute("error", error);
            return "login";
        }

        // 将用户名存放在session中
        HttpSession session = request.getSession();
        session.setAttribute("user", u);
        return "main";
    }

    /**
     * 获得所有标题的json对象
     * 
     */
    @RequestMapping("/findMenu")
    public void findMenu(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        User user = (User) request.getSession().getAttribute("user");
        String user_name = user.getUser_name();

        // 获得指定用户的一级权限
        List<Power> firstpow = powerService.getfirstPow(user_name);

        // 获得用户的二级权限
        List<Power> secPow = powerService.getSecPow(user_name);

        // LinkedHashMap为有序的HashMap
        Map<String, Object> map = new LinkedHashMap<String, Object>();

        // 遍历一级权限
        for (int i = 0; i < firstpow.size(); i++) {
            Map<String, Object> map2 = new HashMap<String, Object>();
            map2.put("name", user_name);
            map2.put("pid", secPow.get(i).getPid());
            // 获取一级权限下的子权限
            List<Power> getchild = powerService.getChildbyName(map2);
            // 将一级权限名和子权限放入map中
            map.put(firstpow.get(i).getPower_name(), getchild);
        }
        // 想响应的输出流中写json数据
        writeToRes(response, map);

    }

}

jsp页面

login.jsp

<body>
      ${error }
   <form action="<%=path %>/power/login.do" method="post">
       用户名:<input type="text" name="user_name"/><br/>
       密码:<input type="password" name="user_pass"/><br/>
       <input type="submit" value="登录"/>
   </form>
  </body>

main.jsp

<script type="text/javascript" src="<%=path%>/js/jquery-1.11.1.js"></script>
  <script type="text/javascript">
  $(function(){
      window.location.href="<%=path%>/power/findMenu.do";
  });
  </script>
  
  <body>
    
  </body> 

项目部署运行之后,登入zhangsan的账户(老师)浏览器中输出

json在线解析后为

 登入lisi账户(学生)

项目总结

项目的主要思路如下:

  首先通过用户名获取到一级权限和二级权限(注意,这里的一级和二级权限并没有关联起来,只是单纯的查询出来);

  然后创建一个LinkedHashMap<String,Object>,遍历一级权限,获得一级权限名当做Map的键,遍历二级权限,获得权限中的pid,即该权限的对应的上级权限的id,通过用户名和pid获得该一级权限下的二级权限,把二级权限当做Map的值;

  最后将map数据转为json数据输出。

 

以上是关于实习小结---权限管理(RBAC)的主要内容,如果未能解决你的问题,请参考以下文章

聊一个 GitHub 上开源的 RBAC 权限管理系统,很6!

RBAC从入门到精通

RBAC之web管理权限思路你懂多少?

讲堂 | Yii2之rbac(基于角色的权限管理)-- 思想与配置

Laravel设计RBAC权限管理出API接口

thinkphp 3.2.3 rbac 超级管理员可登录 其他提示没有权限