前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单的权限(拦截)管理

简单的权限(拦截)管理

作者头像
晚上没宵夜
发布2020-03-11 14:19:22
5380
发布2020-03-11 14:19:22
举报

简单的权限(拦截)管理

  • 给特定的用户以不同的权限来访问不同的资源
  • 很多人把权限模型理解为 用户—权限,这样不是不可以,是不够好。因为如果有100个用户,20个权限呢?给每个用户单独一个个设置不太现实,所以这时候就要加入另一个模块(角色),结构模型如下:

1. 建5张表

用户

CREATE TABLE `user` (
  `id` int(11) NOT NULL,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

角色

CREATE TABLE `role` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

权限

CREATE TABLE `privilege` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

用户角色关系表

CREATE TABLE `user_role` (
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`user_id`,`role_id`),
  CONSTRAINT `role_id_fk` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
  CONSTRAINT `user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

角色权限关系表(外键不能重名)

CREATE TABLE `role_privilege` (
  `role_id` int(11) NOT NULL,
  `privilege_id` int(11) NOT NULL,
  PRIMARY KEY (`role_id`,`privilege_id`),
  CONSTRAINT `privilege_id_fk` FOREIGN KEY (`privilege_id`) REFERENCES `privilege` (`id`),
  CONSTRAINT `role_id_fk1` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

查询用户的所有角色

SELECT * FROM role WHERE id IN (SELECT role_id FROM user_role WHERE user_id=1);

查询角色的所有权限

SELECT * FROM privilege WHERE id IN (SELECT privilege_id FROM role_privilege WHERE role_id=1);

查询用户的所有权限

SELECT * FROM privilege WHERE id IN (SELECT DISTINCT privilege_id FROM role_privilege WHERE role_id IN (SELECT role_id FROM user_role WHERE user_id=1));

2. Bean对象

Privilege

public class Privilege {
    
    int id;
    String name;
    String description;
    
    public Privilege(String name) {
        this.name = name;
    }
    
    //getters和setters
}

3. Dao层(这里只写获取全部权限)

public class PrivilegeDao {
    public HashSet<Privilege> getAllPrivilege(String user_id) {
       
        //各种逻辑操作
        
        return Privileges;
    }
}

4. 拦截功能

  • 使用contains()方法需要在权限类上重写hashCode()和equals()方法的。因为我们比较的是字符串。
public class PermissionInterception implements Filter {
    
    //存放需要权限的资源地址
    private Map<String, Object> map = new HashMap<>();

    public void init(FilterConfig filterConfig) throws ServletException {
        map.put("/addServlet", new Privilege("增加"));
        map.put("/deleteServlet", new Privilege("删除"));
        map.put("/updateServlet", new Privilege("修改"));
        map.put("/findServlet", new Privilege("查账单"));
    }
    
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
         
        //获取请求地址
        String uri = httpServletRequest.getRequestURI();
        
        //公开地址,直接放行
        if (map.get(uri) == null) {
            chain.doFilter(request, response);
            return ;
        }
        
        //需要权限的地址,即要先登录
        if (httpServletRequest.getSession().getAttribute("user") == null) {
            httpServletResponse.sendRedirect("/login.html");
            return;
         }
        
        //查询用户的所有权限,返回一个权限集合
        PrivilegeService privilegeService = new PrivilegeService();
        int user_id = (int) httpServletRequest.getSession().getAttribute("user_id");
        HashSet privileges = privilegeService.getAllPrivilege(user_id);
        
        //是否拥有访问该地址的权限
        if (!privileges.contains(map.get(uri))) {
            httpServletResponse.sendRedirect("/404.html");
            return ;
         }
        
        //通过权限认证,放行
        chain.doFilter(httpServletRequest, httpServletResponse);
        
    }

    public void destroy() {
    }
}

参考Java3y

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-12-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 建5张表
  • 2. Bean对象
  • 3. Dao层(这里只写获取全部权限)
  • 4. 拦截功能
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档