新增角色权限控制

This commit is contained in:
RuoYi 2018-02-26 23:46:10 +08:00
parent c1103a53fd
commit a2af56eadf
25 changed files with 302 additions and 184 deletions

View File

@ -14,9 +14,9 @@ create table sys_dept (
-- ----------------------------
-- 初始化-部门表数据
-- ----------------------------
insert into sys_dept values('1', '0', '研发部', '1', '0');
insert into sys_dept values('2', '0', '测试部', '2', '0');
insert into sys_dept values('3', '0', '市场部', '3', '0');
insert into sys_dept values('1', '0', '研发部', '1', '0');
insert into sys_dept values('2', '0', '测试部', '2', '0');
insert into sys_dept values('3', '0', '市场部', '3', '0');
insert into sys_dept values('4', '1', '研发一部', '1', '0');
insert into sys_dept values('5', '1', '研发二部', '2', '0');
@ -61,6 +61,7 @@ drop table if exists sys_role;
create table sys_role (
role_id int(10) not null auto_increment comment '角色ID',
role_name varchar(30) not null comment '角色名',
role_key varchar(100) not null comment '角色权限字符串',
status int(1) default 0 comment '角色状态:0正常,1禁用',
create_time varchar(30) default null comment '创建时间',
update_time varchar(30) default null comment '更新时间',
@ -72,8 +73,8 @@ create table sys_role (
-- ----------------------------
-- 初始化-角色信息表数据
-- ----------------------------
insert into sys_role values('1', '管理员', 0, '2018-01-01', '', 'system', '管理员');
insert into sys_role values('2', '普通角色', 0, '2018-01-01', '', 'system', '普通角色');
insert into sys_role values('1', '管理员', 'admin', 0, '2018-01-01', '', 'system', '管理员');
insert into sys_role values('2', '普通角色', 'common', 0, '2018-01-01', '', 'system', '普通角色');
@ -89,7 +90,7 @@ create table sys_menu (
url varchar(200) default '' comment '菜单URL',
menu_type char(1) default '' comment '类型:M目录,C菜单,F按钮',
visible int(1) default 0 comment '菜单状态:0显示,1隐藏',
perms varchar(100) default '' comment '权限字符串',
perms varchar(100) default '' comment '菜单权限字符串',
icon varchar(100) default '' comment '菜单图标',
create_time varchar(30) default null comment '创建时间',
update_time varchar(30) default null comment '更新时间',
@ -102,36 +103,36 @@ create table sys_menu (
-- 初始化-菜单信息表数据
-- ----------------------------
-- 一级菜单
insert into sys_menu values('1', '系统管理', '0', '1', '#', 'M', '0', 'system', 'fa fa-gear', '2018-01-01', '', 'system', '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', '#', 'M', '0', 'monitor', 'fa fa-video-camera', '2018-01-01', '', 'system', '系统监控目录');
insert into sys_menu values('1', '系统管理', '0', '1', '#', 'M', '0', '#', 'fa fa-gear', '2018-01-01', '', 'admin', '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', '#', 'M', '0', '#', 'fa fa-video-camera', '2018-01-01', '', 'admin', '系统监控目录');
-- 二级菜单
insert into sys_menu values('3', '用户管理', '1', '1', '/system/user/userList', 'C', '0', 'system:user:list', '#', '2018-01-01', '', 'system', '用户管理菜单');
insert into sys_menu values('4', '角色管理', '1', '2', '/system/role/roleList', 'C', '0', 'system:role:list', '#', '2018-01-01', '', 'system', '角色管理菜单');
insert into sys_menu values('5', '菜单管理', '1', '3', '/system/menu/menuList', 'C', '0', 'system:menu:list', '#', '2018-01-01', '', 'system', '菜单管理菜单');
insert into sys_menu values('6', '操作日志', '1', '4', '/system/operlog/operlogList', 'C', '0', 'system:operlog:list', '#', '2018-01-01', '', 'system', '操作日志菜单');
insert into sys_menu values('7', '登录日志', '1', '5', '/system/userlog/userlogList', 'C', '0', 'system:userlog:list', '#', '2018-01-01', '', 'system', '登录日志菜单');
insert into sys_menu values('8', '在线用户', '2', '1', '/monitor/online', 'C', '0', 'monitor:online', '#', '2018-01-01', '', 'system', '在线用户菜单');
insert into sys_menu values('9', '数据监控', '2', '2', '/monitor/druid/index.html', 'C', '0', 'monitor:druid:list', '#', '2018-01-01', '', 'system', '数据监控菜单');
insert into sys_menu values('3', '用户管理', '1', '1', '/system/user/userList', 'C', '0', 'system:user:list', '#', '2018-01-01', '', 'admin', '用户管理菜单');
insert into sys_menu values('4', '角色管理', '1', '2', '/system/role/roleList', 'C', '0', 'system:role:list', '#', '2018-01-01', '', 'admin', '角色管理菜单');
insert into sys_menu values('5', '菜单管理', '1', '3', '/system/menu/menuList', 'C', '0', 'system:menu:list', '#', '2018-01-01', '', 'admin', '菜单管理菜单');
insert into sys_menu values('6', '操作日志', '1', '4', '/system/operlog/operlogList', 'C', '0', 'system:operlog:list', '#', '2018-01-01', '', 'admin', '操作日志菜单');
insert into sys_menu values('7', '登录日志', '1', '5', '/system/userlog/userlogList', 'C', '0', 'system:userlog:list', '#', '2018-01-01', '', 'admin', '登录日志菜单');
insert into sys_menu values('8', '在线用户', '2', '1', '/monitor/online', 'C', '0', 'monitor:online', '#', '2018-01-01', '', 'admin', '在线用户菜单');
insert into sys_menu values('9', '数据监控', '2', '2', '/monitor/druid/index.html', 'C', '0', 'monitor:druid:list', '#', '2018-01-01', '', 'admin', '数据监控菜单');
--- 三级用户按钮
insert into sys_menu values('10', '用户新增', '3', '1', '/system/user/add', 'F', '0', 'sys:user:add', '#', '2018-01-01', '', 'system', '用户管理新增按钮');
insert into sys_menu values('11', '用户修改', '3', '2', '/system/user/update', 'F', '0', 'sys:user:update', '#', '2018-01-01', '', 'system', '用户管理修改按钮');
insert into sys_menu values('12', '用户删除', '3', '3', '/system/user/delete', 'F', '0', 'sys:user:delete', '#', '2018-01-01', '', 'system', '用户管理删除按钮');
insert into sys_menu values('13', '用户查询', '3', '4', '/system/user/select', 'F', '0', 'sys:user:select', '#', '2018-01-01', '', 'system', '用户管理查询按钮');
insert into sys_menu values('14', '密码修改', '3', '5', '/system/user/pwdUpdate', 'F', '0', 'sys:user:pwdUpdate', '#', '2018-01-01', '', 'system', '用户密码修改按钮');
insert into sys_menu values('10', '用户新增', '3', '1', '/system/user/add', 'F', '0', 'sys:user:add', '#', '2018-01-01', '', 'admin', '用户管理新增按钮');
insert into sys_menu values('11', '用户修改', '3', '2', '/system/user/update', 'F', '0', 'sys:user:update', '#', '2018-01-01', '', 'admin', '用户管理修改按钮');
insert into sys_menu values('12', '用户删除', '3', '3', '/system/user/delete', 'F', '0', 'sys:user:delete', '#', '2018-01-01', '', 'admin', '用户管理删除按钮');
insert into sys_menu values('13', '用户查询', '3', '4', '/system/user/select', 'F', '0', 'sys:user:select', '#', '2018-01-01', '', 'admin', '用户管理查询按钮');
insert into sys_menu values('14', '密码修改', '3', '5', '/system/user/pwdUpdate', 'F', '0', 'sys:user:pwdUpdate', '#', '2018-01-01', '', 'admin', '用户密码修改按钮');
--- 三级角色按钮
insert into sys_menu values('15', '角色新增', '4', '1', '/system/role/add', 'F', '0', 'sys:role:add', '#', '2018-01-01', '', 'system', '角色管理新增按钮');
insert into sys_menu values('16', '角色修改', '4', '2', '/system/role/update', 'F', '0', 'sys:role:update', '#', '2018-01-01', '', 'system', '角色管理修改按钮');
insert into sys_menu values('17', '角色删除', '4', '3', '/system/role/delete', 'F', '0', 'sys:role:delete', '#', '2018-01-01', '', 'system', '角色管理删除按钮');
insert into sys_menu values('18', '角色查询', '4', '4', '/system/role/select', 'F', '0', 'sys:role:select', '#', '2018-01-01', '', 'system', '角色管理查询按钮');
insert into sys_menu values('19', '角色授权', '4', '5', '/system/role/auth', 'F', '0', 'sys:role:auth', '#', '2018-01-01', '', 'system', '角色管理授权按钮');
insert into sys_menu values('15', '角色新增', '4', '1', '/system/role/add', 'F', '0', 'sys:role:add', '#', '2018-01-01', '', 'admin', '角色管理新增按钮');
insert into sys_menu values('16', '角色修改', '4', '2', '/system/role/update', 'F', '0', 'sys:role:update', '#', '2018-01-01', '', 'admin', '角色管理修改按钮');
insert into sys_menu values('17', '角色删除', '4', '3', '/system/role/delete', 'F', '0', 'sys:role:delete', '#', '2018-01-01', '', 'admin', '角色管理删除按钮');
insert into sys_menu values('18', '角色查询', '4', '4', '/system/role/select', 'F', '0', 'sys:role:select', '#', '2018-01-01', '', 'admin', '角色管理查询按钮');
insert into sys_menu values('19', '角色授权', '4', '5', '/system/role/auth', 'F', '0', 'sys:role:auth', '#', '2018-01-01', '', 'admin', '角色管理授权按钮');
--- 三级菜单按钮
insert into sys_menu values('20', '菜单新增', '5', '1', '/system/menu/add', 'F', '0', 'sys:menu:add', '#', '2018-01-01', '', 'system', '菜单管理新增按钮');
insert into sys_menu values('21', '菜单修改', '5', '2', '/system/menu/update', 'F', '0', 'sys:menu:update', '#', '2018-01-01', '', 'system', '菜单管理修改按钮');
insert into sys_menu values('22', '菜单删除', '5', '3', '/system/menu/delete', 'F', '0', 'sys:menu:delete', '#', '2018-01-01', '', 'system', '菜单管理删除按钮');
insert into sys_menu values('20', '菜单新增', '5', '1', '/system/menu/add', 'F', '0', 'sys:menu:add', '#', '2018-01-01', '', 'admin', '菜单管理新增按钮');
insert into sys_menu values('21', '菜单修改', '5', '2', '/system/menu/update', 'F', '0', 'sys:menu:update', '#', '2018-01-01', '', 'admin', '菜单管理修改按钮');
insert into sys_menu values('22', '菜单删除', '5', '3', '/system/menu/delete', 'F', '0', 'sys:menu:delete', '#', '2018-01-01', '', 'admin', '菜单管理删除按钮');
insert into sys_menu values('23', '菜单查询', '5', '4', '/system/menu/select', 'F', '0', 'sys:menu:select', '#', '2018-01-01', '', 'system', '菜单管理查询按钮');
--- 三级日志按钮
insert into sys_menu values('24', '操作日志查询', '4', '5', '/system/operlog/auth', 'F', '0', 'sys:operlog:select', '#', '2018-01-01', '', 'system', '操作日志查询按钮');
insert into sys_menu values('25', '登录日志查询', '4', '5', '/system/userlog/auth', 'F', '0', 'sys:userlog:select', '#', '2018-01-01', '', 'system', '登录日志查询按钮');
insert into sys_menu values('24', '操作日志查询', '4', '5', '/system/operlog/auth', 'F', '0', 'sys:operlog:select', '#', '2018-01-01', '', 'admin', '操作日志查询按钮');
insert into sys_menu values('25', '登录日志查询', '4', '5', '/system/userlog/auth', 'F', '0', 'sys:userlog:select', '#', '2018-01-01', '', 'admin', '登录日志查询按钮');
-- ----------------------------
@ -257,7 +258,6 @@ create table sys_user_online (
sessionId varchar(50) default '' comment '用户会话id',
login_name varchar(50) default '' comment '登录名称',
dept_name varchar(50) default '' comment '部门名称',
role_name varchar(50) default '' comment '角色名称',
ipaddr varchar(50) default '' comment '登录IP地址',
browser varchar(50) default '' comment '浏览器类型',
os varchar(50) default '' comment '操作系统',
@ -268,8 +268,8 @@ create table sys_user_online (
primary key (sessionId)
) engine=innodb default charset=utf8;
insert into sys_user_online(sessionId, login_name, dept_name, role_name, ipaddr, browser, os, status)
values('c3b252c3-2229-4be4-a5f7-7aba4b0c314c', 'admin', '开发部', '管理员', '127.0.0.1', 'Chrome 45', 'Windows 7', 'on_line');
insert into sys_user_online(sessionId, login_name, dept_name, ipaddr, browser, os, status)
values('c3b252c3-2229-4be4-a5f7-7aba4b0c314c', 'admin', '开发部', '127.0.0.1', 'Chrome 45', 'Windows 7', 'on_line');
-- 用户部门表
SELECT * FROM sys_dept;

130
pom.xml
View File

@ -9,7 +9,7 @@
<packaging>jar</packaging>
<name>RuoYi</name>
<description>管理系统</description>
<description>若依管理系统</description>
<parent>
<groupId>org.springframework.boot</groupId>
@ -22,160 +22,141 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<shiro.version>1.3.2</shiro.version>
<thymeleaf-extras-shiro.version>1.2.1</thymeleaf-extras-shiro.version>
<mybatis-spring-boot-starter.version>1.1.1</mybatis-spring-boot-starter.version>
<fastjson.version>1.2.31</fastjson.version>
<druid.version>1.0.28</druid.version>
<commons.lang3.version>3.6</commons.lang3.version>
<bitwalker.version>1.19</bitwalker.version>
<lombok.version>1.16.18</lombok.version>
<mybatisplus-spring-boot-starter.version>1.0.4</mybatisplus-spring-boot-starter.version>
<velocity.version>1.7</velocity.version>
</properties>
<dependencies>
<!-- SpringBoot 核心包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- SpringBoot 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- SpringBoot 拦截器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--web -->
<!-- SpringBoot Web容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- thymeleaf网页解析 -->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
</dependency>
<!--mybatis -->
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- SpringBoot集成mybatis框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
<version>${mybatis-spring-boot-starter.version}</version>
</dependency>
<!--druid -->
<!--阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.28</version>
<version>${druid.version}</version>
</dependency>
<!--commons -->
<!--常用工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
<version>${commons.lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!--shiro -->
<!--Shiro核心框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
<version>${shiro.version}</version>
</dependency>
<!-- Shiro使用Srping框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
<version>${shiro.version}</version>
</dependency>
<!-- shiro ehcache -->
<!-- Shiro使用EhCache缓存框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.3.2</version>
<version>${shiro.version}</version>
</dependency>
<!-- thymeleaf模板引擎和shiro框架的整合 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>1.2.1</version>
<version>${thymeleaf-extras-shiro.version}</version>
</dependency>
<!-- utils -->
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<!--velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!-- ehchache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.19</version>
<version>${bitwalker.version}</version>
</dependency>
<!--lombok依赖-->
<!-- 注解POJO -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
<version>${lombok.version}</version>
</dependency>
<!--Spring框架基本的核心工具-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
@ -187,6 +168,7 @@
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
@ -197,6 +179,7 @@
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
@ -210,4 +193,5 @@
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

View File

@ -1,5 +1,6 @@
package com.ruoyi.framework.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
@ -13,13 +14,20 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
@Configuration
public class BaseConfig extends WebMvcConfigurerAdapter
{
/**
* 强制退出后重定向的地址
*/
@Value("${shiro.user.indexUrl}")
private String indexUrl;
/**
* 默认首页的设置当输入域名是可以自动跳转到默认指定的网页
*/
@Override
public void addViewControllers(ViewControllerRegistry registry)
{
registry.addViewController("/").setViewName("forward:/index");
registry.addViewController("/").setViewName("forward:" + indexUrl);
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
super.addViewControllers(registry);
}

View File

@ -43,6 +43,14 @@ public class ShiroConfig
@Value("${shiro.session.validationInterval}")
private int validationInterval;
// 登录地址
@Value("${shiro.user.loginUrl}")
private String loginUrl;
// 权限认证失败地址
@Value("${shiro.user.unauthorizedUrl}")
private String unauthorizedUrl;
@Autowired
private IMenuService menuService;
@ -174,12 +182,12 @@ public class ShiroConfig
// Shiro的核心安全接口,这个属性是必须的
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 身份认证失败则跳转到登录页面的配置
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setLoginUrl(loginUrl);
// 权限认证失败则跳转到指定页面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauth");
shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);
// 注销成功则跳转到指定页面
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl("/login");
logoutFilter.setRedirectUrl(loginUrl);
// Shiro连接约束配置即过滤链的定义
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// 对静态资源设置匿名访问
@ -219,7 +227,7 @@ public class ShiroConfig
public OnlineSessionFilter onlineSessionFilter()
{
OnlineSessionFilter onlineSessionFilter = new OnlineSessionFilter();
onlineSessionFilter.setLoginUrl("/login");
onlineSessionFilter.setLoginUrl(loginUrl);
return onlineSessionFilter;
}

View File

@ -3,7 +3,6 @@ package com.ruoyi.project.shiro.realm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.ruoyi.framework.constant.CommonConstant;
import com.ruoyi.project.shiro.common.Constants;
import com.ruoyi.project.shiro.common.utils.MessageUtils;
@ -74,12 +73,6 @@ public class LoginService
throw new UserBlockedException(user.getRefuseDes());
}
if (Constants.ROLE_BLOCKED.equals(user.getRole().getStatus()))
{
SystemLogUtils.log(username, CommonConstant.LOGIN_FAIL, MessageUtils.message("role.blocked", user.getRole().getRemark()));
throw new RoleBlockedException(user.getRole().getRemark());
}
SystemLogUtils.log(username, CommonConstant.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
return user;
}

View File

@ -1,6 +1,5 @@
package com.ruoyi.project.shiro.realm;
import java.util.Set;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
@ -15,7 +14,7 @@ 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.ruoyi.common.tools.StringTools;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.project.shiro.exception.JCaptchaException;
import com.ruoyi.project.shiro.exception.user.RoleBlockedException;
@ -24,7 +23,9 @@ import com.ruoyi.project.shiro.exception.user.UserNotExistsException;
import com.ruoyi.project.shiro.exception.user.UserPasswordNotMatchException;
import com.ruoyi.project.shiro.exception.user.UserPasswordRetryLimitExceedException;
import com.ruoyi.project.system.menu.service.IMenuService;
import com.ruoyi.project.system.role.service.IRoleService;
import com.ruoyi.project.system.user.domain.User;
import lombok.extern.slf4j.Slf4j;
/**
@ -39,6 +40,9 @@ public class UserRealm extends AuthorizingRealm
@Autowired
private IMenuService menuService;
@Autowired
private IRoleService roleService;
@Autowired
private LoginService loginService;
@ -49,13 +53,11 @@ public class UserRealm extends AuthorizingRealm
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0)
{
Long userId = ShiroUtils.getUserId();
Set<String> perms = menuService.selectPermsByUserId(userId);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
if (StringTools.isNotEmpty(perms))
{
// // 权限加入AuthorizationInfo认证对象
info.setStringPermissions(perms);
}
// 角色加入AuthorizationInfo认证对象
info.setRoles(roleService.selectRolesByUserId(userId));
// 权限加入AuthorizationInfo认证对象
info.setStringPermissions(menuService.selectPermsByUserId(userId));
return info;
}

View File

@ -2,13 +2,13 @@ package com.ruoyi.project.shiro.session;
import java.io.Serializable;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import com.ruoyi.project.system.online.domain.OnlineSession;
import com.ruoyi.project.system.online.domain.UserOnline;
import com.ruoyi.project.system.online.service.IUserOnlineService;

View File

@ -8,29 +8,30 @@ import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.project.shiro.ShiroConstants;
import com.ruoyi.project.shiro.session.OnlineSessionDAO;
import com.ruoyi.project.system.online.domain.OnlineSession;
import com.ruoyi.project.system.user.domain.User;
/**
* 自定义访问控制
* @author yangzz
*
*/
public class OnlineSessionFilter extends AccessControlFilter
{
/**
* 强制退出后重定向的地址
*/
private String forceLogoutUrl = "/login";
@Value("${shiro.user.loginUrl}")
private String loginUrl;
@Autowired
private OnlineSessionDAO onlineSessionDAO;
public String getForceLogoutUrl()
{
return forceLogoutUrl;
}
/**
* 表示是否允许访问mappedValue就是[urls]配置中拦截器参数部分如果允许访问返回true否则false
*/
@ -58,7 +59,6 @@ public class OnlineSessionFilter extends AccessControlFilter
onlineSession.setUserId(user.getUserId());
onlineSession.setLoginName(user.getLoginName());
onlineSession.setDeptName(user.getDept().getDeptName());
onlineSession.setRoleName(user.getRole().getRoleName());
onlineSession.markAttributeChanged();
}
}
@ -90,7 +90,6 @@ public class OnlineSessionFilter extends AccessControlFilter
@Override
protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException
{
String loginUrl = getForceLogoutUrl();
WebUtils.issueRedirect(request, response, loginUrl);
}

View File

@ -31,6 +31,7 @@ public class SyncOnlineSessionFilter extends PathMatchingFilter
{
OnlineSession session = (OnlineSession) request.getAttribute(ShiroConstants.ONLINE_SESSION);
// 如果session stop了 也不同步
// session停止时间如果stopTimestamp不为null则代表已停止
if (session != null && session.getUserId() != null && session.getStopTimestamp() == null)
{
onlineSessionDAO.syncToDb(session);

View File

@ -4,7 +4,7 @@ import java.util.List;
import com.ruoyi.project.system.menu.domain.Menu;
/**
* 角色 数据层
* 菜单 数据层
*
* @author yangzz
*/

View File

@ -6,7 +6,7 @@ import com.ruoyi.framework.core.dao.DynamicObjectBaseDao;
import com.ruoyi.project.system.menu.domain.Menu;
/**
* 用户 数据层处理
* 菜单 数据层处理
*
* @author yangzz
*/

View File

@ -17,7 +17,7 @@ import com.ruoyi.project.system.menu.domain.Menu;
import com.ruoyi.project.util.TreeUtil;
/**
* 用户 业务层处理
* 菜单 业务层处理
*
* @author yangzz
*/

View File

@ -19,9 +19,6 @@ public class OnlineSession extends SimpleSession
// 部门名称
private String deptName;
// 角色名称
private String roleName;
// 登录IP地址
private String host;
@ -99,16 +96,6 @@ public class OnlineSession extends SimpleSession
this.deptName = deptName;
}
public String getRoleName()
{
return roleName;
}
public void setRoleName(String roleName)
{
this.roleName = roleName;
}
public OnlineStatus getStatus()
{
return status;

View File

@ -21,9 +21,6 @@ public class UserOnline
// 登录名称
private String loginName;
// 角色名称
private String roleName;
// 登录IP地址
private String ipaddr;
@ -57,7 +54,6 @@ public class UserOnline
online.setSessionId(String.valueOf(session.getId()));
online.setDeptName(session.getDeptName());
online.setLoginName(session.getLoginName());
online.setRoleName(session.getRoleName());
online.setStartTimestamp(session.getStartTimestamp());
online.setLastAccessTime(session.getLastAccessTime());
online.setExpireTime(session.getTimeout());

View File

@ -0,0 +1,21 @@
package com.ruoyi.project.system.role.dao;
import java.util.List;
/**
* 角色表 数据层
*
* @author yangzz
*/
public interface IRoleDao
{
/**
* 根据用户ID查询角色
*
* @param userId 用户ID
* @return 角色列表
*/
public List<String> selectRolesByUserId(Long userId);
}

View File

@ -0,0 +1,39 @@
package com.ruoyi.project.system.role.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.ruoyi.framework.core.dao.DynamicObjectBaseDao;
/**
* 角色 数据层处理
*
* @author yangzz
*/
@Repository("roleDao")
public class RoleDaoImpl extends DynamicObjectBaseDao implements IRoleDao
{
/**
* 根据用户ID查询角色
*
* @param userId 用户ID
* @return 角色列表
*/
@Override
public List<String> selectRolesByUserId(Long userId)
{
List<String> permsList = null;
try
{
permsList = this.findForList("SystemRoleMapper.selectRolesByUserId", userId);
}
catch (Exception e)
{
e.printStackTrace();
}
return permsList;
}
}

View File

@ -0,0 +1,21 @@
package com.ruoyi.project.system.role.service;
import java.util.Set;
/**
* 角色业务层
*
* @author yangzz
*/
public interface IRoleService
{
/**
* 根据用户ID查询角色
*
* @param userId 用户ID
* @return 权限列表
*/
public Set<String> selectRolesByUserId(Long userId);
}

View File

@ -0,0 +1,45 @@
package com.ruoyi.project.system.role.service;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.system.role.dao.IRoleDao;
/**
* 角色 业务层处理
*
* @author yangzz
*/
@Service("roleService")
public class RoleServiceImpl implements IRoleService
{
@Autowired
private IRoleDao roleDao;
/**
* 根据用户ID查询权限
*
* @param userId 用户ID
* @return 权限列表
*/
@Override
public Set<String> selectRolesByUserId(Long userId)
{
List<String> perms = roleDao.selectRolesByUserId(userId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms)
{
if (StringUtils.isNotBlank(perm))
{
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
}
}
return permsSet;
}
}

View File

@ -1,7 +1,6 @@
package com.ruoyi.project.system.user.domain;
import com.ruoyi.project.system.dept.domain.Dept;
import com.ruoyi.project.system.role.domain.Role;
import lombok.Data;
/**
@ -36,7 +35,5 @@ public class User
private String createTime;
// 部门对象
private Dept dept;
// 角色对象
private Role role;
}

View File

@ -35,6 +35,13 @@ mybatis:
configLocation: classpath:mybatis/mybatis-config.xml
# Shiro
shiro:
user:
# 登录地址
loginUrl: /login
# 权限认证失败地址
unauthorizedUrl: /unauth
# 首页地址
indexUrl: /index
session:
# Session超时时间默认30分钟
expireTime: 30

View File

@ -8,7 +8,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<id property="sessionId" column="sessionId" />
<result property="loginName" column="login_name" />
<result property="deptName" column="dept_name" />
<result property="roleName" column="role_name" />
<result property="ipaddr" column="ipaddr" />
<result property="browser" column="browser" />
<result property="os" column="os" />
@ -33,8 +32,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<insert id="saveByOnline" parameterType="UserOnline">
replace into sys_user_online(sessionId, login_name, dept_name, role_name, ipaddr, browser, os, status, start_timestsamp, last_access_time, expireTime)
values (#{sessionId}, #{loginName}, #{deptName}, #{roleName}, #{ipaddr}, #{browser}, #{os}, #{status}, #{startTimestamp}, #{lastAccessTime}, #{expireTime})
replace into sys_user_online(sessionId, login_name, dept_name, ipaddr, browser, os, status, start_timestsamp, last_access_time, expireTime)
values (#{sessionId}, #{loginName}, #{deptName}, #{ipaddr}, #{browser}, #{os}, #{status}, #{startTimestamp}, #{lastAccessTime}, #{expireTime})
</insert>
<delete id="deleteByOnlineId" parameterType="String">

View File

@ -0,0 +1,25 @@
<?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="SystemRoleMapper">
<resultMap type="Role" id="RoleResult">
<id property="roleId" column="role_id" />
<result property="roleName" column="role_name" />
<result property="status" column="status" />
<result property="createTime" column="create_time" />
<result property="updateTime" column="update_time" />
<result property="updateBy" column="update_by" />
<result property="remark" column="remark" />
</resultMap>
<select id="selectRolesByUserId" parameterType="Long" resultType="String">
select distinct r.role_key
from sys_user u
left join sys_user_role ur on u.user_id = ur.user_id
left join sys_role r on ur.role_id = r.role_id
where ur.user_id = #{userId}
</select>
</mapper>

View File

@ -17,7 +17,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="refuseDes" column="refuse_des" />
<result property="createTime" column="create_time" />
<association property="dept" column="dept_id" javaType="Dept" resultMap="deptResult"/>
<association property="role" column="role_id" javaType="Role" resultMap="roleResult"/>
</resultMap>
<resultMap id="deptResult" type="Dept">
@ -28,30 +27,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="status" column="dept_status" />
</resultMap>
<resultMap id="roleResult" type="Role">
<id property="roleId" column="role_id" />
<result property="roleName" column="role_name" />
<result property="status" column="role_status" />
<result property="createTime" column="create_time" />
<result property="updateTime" column="update_time" />
<result property="updateBy" column="update_by" />
<result property="remark" column="remark" />
</resultMap>
<select id="queryUserListByCond" parameterType="User" resultMap="UserResult">
select * from sys_user
</select>
<select id="selectByUserName" parameterType="String" resultMap="UserResult">
select u.user_id, u.dept_id, u.login_name, u.user_name, u.email, u.phonenumber, u.password, u.salt, u.status, u.refuse_des, u.create_time,
d.dept_id, d.parent_id, d.dept_name, d.order_num, d.status as dept_status,
r.role_id, r.role_name, r.status as role_status, r.remark
d.dept_id, d.parent_id, d.dept_name, d.order_num, d.status as dept_status
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join sys_user_role ur on u.user_id = ur.user_id
left join sys_role r on ur.role_id = r.role_id
where u.login_name = #{username}
</select>

View File

@ -32,7 +32,7 @@
<img src="img/profile_small.jpg" alt="image" class="img-circle" height="60" width="60"/></span>
<a data-toggle="dropdown" class="dropdown-toggle" href="#">
<span class="clear"><span class="block m-t-xs"><strong class="font-bold" th:text="${user.userName}">RuoYi</strong></span>
<span class="text-muted text-xs block" th:text="${user.dept.deptName} + '.' + ${user.role.roleName}">超级管理员<b class="caret"></b></span> </span> </a>
<span class="text-muted text-xs block" th:text="${user.dept.deptName}">研发部<b class="caret"></b></span> </span> </a>
<ul class="dropdown-menu animated fadeInRight m-t-xs">
<li><a href="profile.html">个人信息</a></li>
<li class="divider"></li>

View File

@ -29,7 +29,8 @@
</div>
</div>
</div>
<!-- <a shiro:hasPermission="system:user:list" href="#">测试菜单</a> -->
<!-- <a shiro:hasRole="admin" href="#">测试角色</a> -->
<div th:include="include :: footer"></div>
<script type="text/javascript" src="/js/appjs/monitor/online/online.js"></script>
</body>