一、前言

在大型的信息管理系统中,经常涉及到权限管理系统
下面来个 demo,很多复杂的系统的设计都来自它
代码已经放到github上了,地址:https://github.com/larger5/shiro_urp.git

2018.4.3 版本0.5 在 SpringBoot 中使用 Shiro+MySQL 做登录拦截
2018.4.6 版本1.0 使用 Shiro 设计基于用户、角色、权限的通用权限管理系统
以后继续更新,如用户、角色、权限 CRUD 等,真正做到所谓的权限管理系统

二、数据库表的设计

下面使用 SpringBoot + JPA 的,自动生成如下的表
用户角色多对多、角色权限多对多,设计一个通用的权限系统(无论初衷是一个用户多个角色还是一个角色)

三、效果

说明:

①UI:

  使用了 LayUI 简单优化一下界面

②角色所含权限:

   p:selectip:select、insertvip:select、insert、update、delete

③权限:

   selectinsertupdatedelete

以使用 itaem (VIP)为例

图解:
有:① select、insert、update、delete 权限 ② vip 角色
无:ip角色、p角色,点击后都是没有反应的

四、代码(github 平台上看)

① Controller(重点)

package com.cun.controller;import java.util.HashMap;
import java.util.Map;import javax.servlet.http.HttpSession;
import javax.validation.Valid;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import com.cun.entity.User;import springfox.documentation.swagger2.annotations.EnableSwagger2;@EnableSwagger2
@RestController
@RequestMapping("/user")
public class UserController {@PostMapping("/login")public Map<String, Object> login(@Valid User user, BindingResult bindingResult, HttpSession session) {Map<String, Object> map = new HashMap<String, Object>();// 1、JSR303if (bindingResult.hasErrors()) {map.put("success", false);map.put("errorInfo", bindingResult.getFieldError().getDefaultMessage());return map;}// 2、ShiroSubject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword());try {subject.login(token);map.put("success", true);return map;} catch (Exception e) {e.printStackTrace();map.put("success", false);map.put("errorInfo", "用户名或者密码错误!");return map;}}

④ ShiroConfig(重点)

package com.cun.config;import java.util.LinkedHashMap;
import java.util.Map;import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.apache.shiro.mgt.SecurityManager;
import com.cun.realm.MyRealm;/*** Shiro配置类* @author linhongcun**/
@Configuration
public class ShiroConfig {/*** ShiroFilterFactoryBean 处理拦截资源文件问题。* 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在* 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager** Filter Chain定义说明 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过* 3、部分过滤器可指定参数,如perms,roles**/@Beanpublic ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// 必须设置 SecurityManagershiroFilterFactoryBean.setSecurityManager(securityManager);// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面shiroFilterFactoryBean.setLoginUrl("/login.html");// 拦截器.Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();// 配置不会被拦截的链接 顺序判断filterChainDefinitionMap.put("/static/**", "anon");filterChainDefinitionMap.put("/user/login", "anon");//测试权限用filterChainDefinitionMap.put("/swagger-ui.html", "anon");// 配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了filterChainDefinitionMap.put("/logout", "logout");// 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 :这是一个坑呢,一不小心代码就不好使了;// ① authc:所有url都必须认证通过才可以访问; ② anon:所有url都都可以匿名访问filterChainDefinitionMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}@Beanpublic SecurityManager securityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 设置realm.securityManager.setRealm(myRealm());return securityManager;}/*** 身份认证realm; (这个需要自己写,账号密码校验;权限等)* * @return*/@Beanpublic MyRealm myRealm() {MyRealm myRealm = new MyRealm();return myRealm;}/*** Shiro生命周期处理器* @return*/@Beanpublic LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}/*** 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证* 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能* @return*/@Bean@DependsOn({ "lifecycleBeanPostProcessor" })public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();advisorAutoProxyCreator.setProxyTargetClass(true);return advisorAutoProxyCreator;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());return authorizationAttributeSourceAdvisor;}
}

⑤ MyRealm(重点)

package com.cun.realm;import java.util.HashSet;
import java.util.List;
import java.util.Set;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;import com.cun.dao.PermissionDao;
import com.cun.dao.RoleDao;
import com.cun.dao.UserDao;
import com.cun.entity.Permission;
import com.cun.entity.Role;
import com.cun.entity.User;public class MyRealm extends AuthorizingRealm {@Autowiredprivate UserDao userDao;@Autowiredprivate RoleDao roleDao;@Autowiredprivate PermissionDao permissionDao;/*** 授权*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String userName=(String) SecurityUtils.getSubject().getPrincipal();SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();Set<String> roles=new HashSet<String>();List<Role> rolesByUserName = roleDao.getRolesByUserName(userName);for(Role role:rolesByUserName) {roles.add(role.getRoleName());}List<Permission> permissionsByUserName = permissionDao.getPermissionsByUserName(userName);for(Permission permission:permissionsByUserName) {info.addStringPermission(permission.getPermissionName());}info.setRoles(roles);return info;}/*** 认证*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("token.getPrincipal:" + token.getPrincipal());System.out.println("token.getCredentials:" + token.getCredentials());String userName = token.getPrincipal().toString();User user = userDao.getUserByUserName(userName);if (user != null) {// Object principal, Object credentials, String realmNameAuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), getName());return authcInfo;} else {return null;}}}

五、其他

① sql

CREATE DATABASE /*!32312 IF NOT EXISTS*/`urp` /*!40100 DEFAULT CHARACTER SET utf8 */;USE `urp`;/*Table structure for table `t_permission` */DROP TABLE IF EXISTS `t_permission`;CREATE TABLE `t_permission` (`id` int(11) NOT NULL AUTO_INCREMENT,`permission_name` varchar(50) DEFAULT NULL,`remarks` varchar(1000) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;/*Data for the table `t_permission` */insert  into `t_permission`(`id`,`permission_name`,`remarks`) values (1,'select','查询'),(2,'insert','增加'),(3,'update','更新'),(4,'delete','删除');/*Table structure for table `t_role` */DROP TABLE IF EXISTS `t_role`;CREATE TABLE `t_role` (`id` int(11) NOT NULL AUTO_INCREMENT,`remarks` varchar(1000) DEFAULT NULL,`role_name` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;/*Data for the table `t_role` */insert  into `t_role`(`id`,`remarks`,`role_name`) values (1,'普通角色','p'),(2,'重要角色','ip'),(3,'超级角色','vip');/*Table structure for table `t_role_permission` */DROP TABLE IF EXISTS `t_role_permission`;CREATE TABLE `t_role_permission` (`id` int(11) NOT NULL AUTO_INCREMENT,`remarks` varchar(1000) DEFAULT NULL,`permission_id` int(11) DEFAULT NULL,`role_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `FKjobmrl6dorhlfite4u34hciik` (`permission_id`),KEY `FK90j038mnbnthgkc17mqnoilu9` (`role_id`),CONSTRAINT `FK90j038mnbnthgkc17mqnoilu9` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`),CONSTRAINT `FKjobmrl6dorhlfite4u34hciik` FOREIGN KEY (`permission_id`) REFERENCES `t_permission` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;/*Data for the table `t_role_permission` */insert  into `t_role_permission`(`id`,`remarks`,`permission_id`,`role_id`) values (1,'授予普通角色select权限',1,1),(2,'授予重要角色select权限',1,2),(3,'授予重要角色insert权限',2,2),(4,'授予超级角色select权限',1,3),(5,'授予超级角色insert权限',2,3),(6,'授予超级角色update权限',3,3),(7,'授予超级角色delete权限',4,3);/*Table structure for table `t_user` */DROP TABLE IF EXISTS `t_user`;CREATE TABLE `t_user` (`id` int(11) NOT NULL AUTO_INCREMENT,`password` varchar(100) NOT NULL,`remarks` varchar(1000) DEFAULT NULL,`user_name` varchar(100) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;/*Data for the table `t_user` */insert  into `t_user`(`id`,`password`,`remarks`,`user_name`) values (1,'123','JKing团队','jking'),(2,'123','网维团队','wteam'),(3,'123','ITAEM团队','itaem');/*Table structure for table `t_user_role` */DROP TABLE IF EXISTS `t_user_role`;CREATE TABLE `t_user_role` (`id` int(11) NOT NULL AUTO_INCREMENT,`remarks` varchar(1000) DEFAULT NULL,`role_id` int(11) DEFAULT NULL,`user_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `FKa9c8iiy6ut0gnx491fqx4pxam` (`role_id`),KEY `FKq5un6x7ecoef5w1n39cop66kl` (`user_id`),CONSTRAINT `FKq5un6x7ecoef5w1n39cop66kl` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`),CONSTRAINT `FKa9c8iiy6ut0gnx491fqx4pxam` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;/*Data for the table `t_user_role` */insert  into `t_user_role`(`id`,`remarks`,`role_id`,`user_id`) values (1,'授予JKing团队普通角色',1,1),(2,'授予网维团队重要角色',2,2),(3,'授予ITAEM团队超级角色',3,3);

转载https://blog.csdn.net/larger5/article/details/79838212

转载于:https://www.cnblogs.com/sunBinary/p/11010677.html

使用 Shiro 设计基于用户、角色、权限的通用权限管理系统相关推荐

  1. 基于用户角色的数据库智能监控系统应用场景分析

    摘要:本文尝试从概念和逻辑上推导了基于用户角色的数据库智能监控系统的可能应用场景. 本文分享自华为云社区<GaussDB(DWS)数据库智能监控系统应用场景分析>,原文作者:鲁大师. 与互 ...

  2. 课程设计-基于SSM的美容美发造型预约管理系统代码Java理发剪发设计造型系统vue美发店管理系统

    课程设计-基于SSM的美容美发造型预约管理系统代码Java理发剪发设计造型系统vue美发店管理系统 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台框架: ...

  3. springboot整合shiro,mybatis-plus实现用户角色,权限管控.(完整demo)

    资源下载链接:https://download.csdn.net/download/dayonglove2018/13960978 shiro是轻量级的权限管控框架.很早前就接触过.不过一直没有实现了 ...

  4. 系统权限控制设计001---RBAC用户角色权限设计方案

    RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成"用 ...

  5. 【产品实战-乘风游旅游App】3.0 乘风游的产品设计之用户角色

    本期会讲解乘风游的用户角色的定位.通过讲故事的方式,构造人物角色,明确产品需求. 场景分析 案例一 工作地在上海的张强,准备本周末去杭州游玩两日. 出行前:他先通过乘风游的攻略模块,搜索目的地:杭州的 ...

  6. android移动停车车位管理系统的分析与设计,基于Android与WiFi的智能停车管理系统的设计与实现...

    摘要: 伴随着我国人民平均收入的不断提高,汽车已经成为人们出行的主流交通工具,城区商业金融和医疗服务中心的"停车难"成为阻碍城市交通发展的一大难题.传统的停车引导方式缺乏高效的停车 ...

  7. python设置文件权限_python通用权限框架

    EasyPermission 适用于由Django开发的网站的通用权限框架,只要设置好配置文件就快速做好权限管理,而且还支持各种条件的自定制扩展. 功能: 1.权限验证 -- 支持添加临时权限 支持临 ...

  8. 基于likeadmin管理后台搭建—通用CRM管理系统

    前言 likeadmin是一款免费开源的通用后台框架系统,可以快速开发前后业务.代码生成器.API模块.uniapp端都已具备,下面是基于likeadmin-Java开发的客户关系管理系统,使用它来管 ...

  9. 基于VUE3+Layui从头搭建通用后台管理系统(前端篇)一:项目规划及初始化

    一.项目内容   使用vue3+Layui实现通用管理系统前端,使用vue3+layui搭建系统UI界面,使用nodejs搭建模拟web服务器,使用echarts实现系统可视化模块,可以此项目为基础进 ...

最新文章

  1. OBS源代码阅读笔记
  2. springboot自定义配置文件
  3. git Rebase 变基 教程
  4. 深度理解Android InstantRun原理以及源码分析
  5. poj 1190 生日蛋糕
  6. mfc界面的onvscroll没反应_电脑小技巧之360安全卫士卸载不掉怎么办?只因一个开关没打开...
  7. 蓝桥杯 ADV-83算法提高 寻找三位数
  8. 最简单的基于FFmpeg的移动端例子:IOS 视频转码器
  9. SpringBoot+Swagger2
  10. 初识Quartz (一)
  11. LUT Gallery for mac插件不能用要怎么办呢?教程来了,快来看看吧
  12. cad转dwf格式怎么转换?
  13. AVOD阅读笔记(一):摘要+特征提取----Aggregate View Obeject Detection network
  14. Javashop连锁门店管理系统带您玩转获客
  15. QT通过ODBC连接MySQL数据库
  16. 【2022年】浙江省专升本数学全面总结-(空间解析几何与向量代数)
  17. 专科计算机教育的现状,探析高职计算机专业英语教学现状
  18. C++ STL使用实例
  19. 实验吧web天网管理系统
  20. Oracle的学习心得和知识总结(七)|Oracle数据库Literals技术详解

热门文章

  1. 【译】特征工程最佳实践
  2. 3-unit10 iptables
  3. 习惯几乎可以绑住一切,只是不能绑住偶然。比如那只偶然尝了鲜血的老虎。...
  4. 关于客户需求分析的讨论
  5. python计算选手最后得分并取出前三名_在Python中存储最后3个分数并删除旧分数并计算平均值?...
  6. python神经网络风格_[Deep-Learning-with-Python]使用LSTM生成尼采风格文章
  7. 多线程不重复读取数据_用 PHP 实现多线程编程
  8. 数据权限设计思路_后台权限管理设计思路:三种模型分析
  9. java开发面试复试_面试java开发,面试官会问哪些问题?
  10. JSP笔记-点击量统计