diff --git a/spring-boot-demo-parent/pom.xml b/spring-boot-demo-parent/pom.xml index e4a4268..1134d25 100644 --- a/spring-boot-demo-parent/pom.xml +++ b/spring-boot-demo-parent/pom.xml @@ -25,8 +25,10 @@ ../spring-boot-demo-orm-mybatis ../spring-boot-demo-cache-redis ../spring-boot-demo-swagger + ../spring-boot-demo-rabc-shiro-mybatis ../spring-boot-demo-ureport2 ../spring-boot-demo-war + ../spring-boot-demo-util diff --git a/spring-boot-demo-rabc-shiro-mybatis/pom.xml b/spring-boot-demo-rabc-shiro-mybatis/pom.xml new file mode 100644 index 0000000..68b3011 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/pom.xml @@ -0,0 +1,118 @@ + + + 4.0.0 + + spring-boot-demo-rabc-shiro-mybatis + 0.0.1-SNAPSHOT + jar + + spring-boot-demo-rabc-shiro-mybatis + Demo project for Spring Boot + + + com.xkcoding + spring-boot-demo-parent + 0.0.1-SNAPSHOT + ../spring-boot-demo-parent + + + + 1.3.2 + 2.4.2.1-RELEASE + 1.3.1 + 1.1.5 + 1.1.1 + 1.1.0 + + + + ${basedir}/src/main/java + com.xkcoding.springbootdemorabcshiromybatis.dao + com.xkcoding.springbootdemorabcshiromybatis.model + + ${basedir}/src/main/resources + mapper + + 3.4.0 + 5.1.29 + + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis.starter.version} + + + + com.alibaba + druid-spring-boot-starter + ${druid.starter.version} + + + + tk.mybatis + mapper-spring-boot-starter + ${mapper.version} + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.version} + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + org.crazycake + shiro-redis + ${shiro.redis.version} + + + + com.xkcoding + spring-boot-demo-util + 0.0.1-SNAPSHOT + + + com.xiaoleilu + hutool-all + + + + + + + + + org.mybatis.generator + mybatis-generator-maven-plugin + 1.3.2 + + ${basedir}/src/main/resources/generator/generatorConfig.xml + true + true + + + + mysql + mysql-connector-java + ${mysql.version} + + + tk.mybatis + mapper + ${mapper.generator.version} + + + + + spring-boot-demo-rabc-shiro-mybatis + + + \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/SpringBootDemoRabcShiroMybatisApplication.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/SpringBootDemoRabcShiroMybatisApplication.java new file mode 100644 index 0000000..5714ea3 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/SpringBootDemoRabcShiroMybatisApplication.java @@ -0,0 +1,17 @@ +package com.xkcoding.springbootdemorabcshiromybatis; + +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@MapperScan(basePackages = {"com.xkcoding.springbootdemorabcshiromybatis.dao"}) +@Slf4j +public class SpringBootDemoRabcShiroMybatisApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootDemoRabcShiroMybatisApplication.class, args); + log.info("SpringBootDemoRabcShiroMybatisApplication 启动成功。。。。"); + } +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/config/DBInitConfig.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/config/DBInitConfig.java new file mode 100644 index 0000000..c6209ee --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/config/DBInitConfig.java @@ -0,0 +1,30 @@ +package com.xkcoding.springbootdemorabcshiromybatis.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +/** + *

+ * 数据初始化,实现 CommandLineRunner 接口,启动 springboot 后自动执行,如果有多个这个类可以根据 @Order 来指定执行顺序 + *

+ * + * @package: com.xkcoding.springbootdemorabcshiromybatis + * @description: 数据初始化 + * @author: yangkai.shen + * @date: Created in 2017/11/29 下午4:32 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +@Component +@Slf4j +public class DBInitConfig implements CommandLineRunner { + + @Override + public void run(String... strings) throws Exception { + log.info("正在初始化数据。。。"); + log.info("数据初始化完成。。。"); + } + +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/config/ShiroConfig.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/config/ShiroConfig.java new file mode 100644 index 0000000..8ad9d4d --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/config/ShiroConfig.java @@ -0,0 +1,78 @@ +package com.xkcoding.springbootdemorabcshiromybatis.config; + +import com.google.common.collect.Maps; +import com.xkcoding.springbootdemorabcshiromybatis.shiro.MyShiroRealm; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.mgt.DefaultSecurityManager; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Map; + +/** + * Shiro 配置 + * + * @package: com.xkcoding.springbootdemorabcshiromybatis.config + * @description: Shiro 配置 + * @author: yangkai.shen + * @date: Created in 2017/11/29 下午3:24 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +@Configuration +@Slf4j +public class ShiroConfig { + + @Bean + public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { + ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); + // 必须设置 securityManager + shiroFilterFactoryBean.setSecurityManager(securityManager); + + // 设置登录页面,默认是 Web 工程目录下的"/login.jsp" + shiroFilterFactoryBean.setLoginUrl("/login"); + // 设置登陆成功后的页面 + shiroFilterFactoryBean.setSuccessUrl("/index"); + // 设置未授权页面 + shiroFilterFactoryBean.setUnauthorizedUrl("/403"); + + // 配置拦截器链,注意配置的顺序,很关键 + // 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 + // authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问 + Map filterChainDefinitionMap = Maps.newLinkedHashMap(); + // 配置可以被匿名访问的地址 + filterChainDefinitionMap.put("/static/**", "anon"); + filterChainDefinitionMap.put("/ajaxLogin", "anon"); + // 配置 logout,登出部分逻辑由 shiro 为我们实现 + filterChainDefinitionMap.put("/logout", "logout"); + // 配置自定义权限 + filterChainDefinitionMap.put("/add", "perms[权限添加]"); + filterChainDefinitionMap.put("/**", "authc"); + + shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); + log.info("ShiroFilterFactoryBean 注入成功"); + + return shiroFilterFactoryBean; + } + + @Bean + public SecurityManager securityManager(MyShiroRealm myShiroRealm) { + DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager(); + // 设置 Realm + // 在 shiro 中,最终是通过 Realm 来获取应用程序中的用户、角色及权限信息的。 + // 通常情况下,在 Realm 中会直接从我们的数据源中获取 shiro 需要的验证信息。 + // 可以说,Realm 是专用于安全框架的 DAO。 + defaultSecurityManager.setRealm(myShiroRealm); + + return defaultSecurityManager; + } + + @Bean + public MyShiroRealm myShiroRealm() { + return new MyShiroRealm(); + } +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/constrant/factory/Constant.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/constrant/factory/Constant.java new file mode 100644 index 0000000..d3d1a50 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/constrant/factory/Constant.java @@ -0,0 +1,124 @@ +package com.xkcoding.springbootdemorabcshiromybatis.constrant.factory; + +import java.util.List; + +/** + *

+ * 常量生产工厂的接口 + *

+ * + * @package: com.xkcoding.springbootdemorabcshiromybatis.constrant.factory + * @description: 常量生产工厂的接口 + * @author: yangkai.shen + * @date: Created in 2017/12/6 下午3:51 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +public interface Constant { + + String ADMIN_NAME = "超级管理员"; + + String COMMA = ","; + String SEMI = ";"; + String SEPARATE = "|"; + String PATH_SEPARATE = "/"; + String PERCENT = "%"; + + /** + * 根据用户id获取用户名称 + * + * @param userId 用户id + * @return 用户名称 + */ + String getRealNameById(Integer userId); + + /** + * 根据用户id获取用户账号 + * + * @param userId 用户id + * @return 用户账号 + */ + String getUsernameById(Integer userId); + + /** + * 根据角色id获取角色名称 + * + * @param roleId 角色id + * @return 角色名称 + */ + String getRoleName(Integer roleId); + + /** + * 根据角色id列表获取角色名称列表 + * + * @param roleIds 角色id列表 + * @return 角色名称列表 + */ + List getRoleNames(List roleIds); + + /** + * 根据用户id获取角色id列表 + * + * @param userId 用户id + * @return 角色id列表 + */ + List getRoleIds(Integer userId); + + /** + * 根据部门id获取部门名称 + * + * @param deptId 部门id + * @return 部门名称 + */ + String getDeptName(Integer deptId); + + /** + * 根据权限id获取权限名称 + * + * @param aclId 权限id + * @return 权限名称 + */ + String getAclName(Integer aclId); + + /** + * 根据权限编号获取权限名称 + * + * @param code 权限编号 + * @return 权限名称 + */ + String getAclNameByCode(String code); + + /** + * 根据状态码获取用户登录状态 + * + * @param code 状态码 + * @return 状态 + */ + String getUserStatusName(Integer code); + + /** + * 根据状态码获取权限状态 + * + * @param code 状态码 + * @return 状态 + */ + String getAclStatusName(Integer code); + + /** + * 获取子部门id + * + * @param deptId 当前部门id + * @return 所有子部门id + */ + List getSubDeptId(Integer deptId); + + /** + * 获取所有父部门id + * + * @param deptId 当前部门id + * @return 所有父部门id + */ + List getParentDeptIds(Integer deptId); + +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/constrant/factory/ConstantFactory.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/constrant/factory/ConstantFactory.java new file mode 100644 index 0000000..372d2e6 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/constrant/factory/ConstantFactory.java @@ -0,0 +1,157 @@ +package com.xkcoding.springbootdemorabcshiromybatis.constrant.factory; + +import com.google.common.collect.Lists; +import com.xiaoleilu.hutool.util.StrUtil; +import com.xkcoding.springbootdemorabcshiromybatis.dao.*; +import com.xkcoding.springbootdemorabcshiromybatis.enums.AclStatusEnum; +import com.xkcoding.springbootdemorabcshiromybatis.enums.UserStatusEnum; +import com.xkcoding.springbootdemorabcshiromybatis.model.*; +import com.xkcoding.springbootdemorabcshiromybatis.util.SpringContextHolder; +import org.springframework.context.annotation.DependsOn; +import org.springframework.stereotype.Component; +import tk.mybatis.mapper.entity.Example; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 常量的生产工厂 + *

+ * + * @package: com.xkcoding.springbootdemorabcshiromybatis.constrant.factory + * @description: 常量的生产工厂 + * @author: yangkai.shen + * @date: Created in 2017/12/6 下午4:01 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +@Component +@DependsOn("springContextHolder") +public class ConstantFactory implements Constant { + + private MybatisShiroAclMapper aclMapper = SpringContextHolder.getBean(MybatisShiroAclMapper.class); + private MybatisShiroDeptMapper deptMapper = SpringContextHolder.getBean(MybatisShiroDeptMapper.class); + private MybatisShiroUserMapper userMapper = SpringContextHolder.getBean(MybatisShiroUserMapper.class); + private MybatisShiroRoleMapper roleMapper = SpringContextHolder.getBean(MybatisShiroRoleMapper.class); + private MybatisShiroRoleUserMapper roleUserMapper = SpringContextHolder.getBean(MybatisShiroRoleUserMapper.class); + + + public static Constant me() { + return SpringContextHolder.getBean("constantFactory"); + } + + @Override + public String getRealNameById(Integer userId) { + MybatisShiroUser user = userMapper.selectByPrimaryKey(userId); + if (user != null) { + return user.getRealname(); + } + return null; + } + + @Override + public String getUsernameById(Integer userId) { + MybatisShiroUser user = userMapper.selectByPrimaryKey(userId); + if (user != null && StrUtil.isNotEmpty(user.getUsername())) { + return user.getUsername(); + } + return null; + } + + @Override + public String getRoleName(Integer roleId) { + MybatisShiroRole role = roleMapper.selectByPrimaryKey(roleId); + if (role != null && StrUtil.isNotEmpty(role.getName())) { + return role.getName(); + } + return null; + } + + @Override + public List getRoleNames(List roleIds) { + return roleIds.stream().map(id -> getRoleName(id)).collect(Collectors.toList()); + } + + @Override + public List getRoleIds(Integer userId) { + MybatisShiroRoleUser param = new MybatisShiroRoleUser(); + param.setUserId(userId); + List roleUser = roleUserMapper.select(param); + return roleUser.stream().map(v -> v.getRoleId()).collect(Collectors.toList()); + } + + @Override + public String getDeptName(Integer deptId) { + MybatisShiroDept dept = deptMapper.selectByPrimaryKey(deptId); + if (dept != null && StrUtil.isNotEmpty(dept.getName())) { + return dept.getName(); + } + return null; + } + + @Override + public String getAclName(Integer aclId) { + MybatisShiroAcl acl = aclMapper.selectByPrimaryKey(aclId); + if (acl != null && StrUtil.isNotEmpty(acl.getName())) { + return acl.getName(); + } + return null; + } + + @Override + public String getAclNameByCode(String code) { + if (StrUtil.isNotBlank(code)) { + return null; + } else { + MybatisShiroAcl param = new MybatisShiroAcl(); + param.setCode(code); + MybatisShiroAcl acl = aclMapper.selectOne(param); + if (acl != null && StrUtil.isNotEmpty(acl.getName())) { + return acl.getName(); + } + return null; + } + } + + @Override + public String getUserStatusName(Integer code) { + return UserStatusEnum.valueOf(code); + } + + @Override + public String getAclStatusName(Integer code) { + return AclStatusEnum.valueOf(code); + } + + @Override + public List getSubDeptId(Integer deptId) { + Example example = new Example(MybatisShiroDept.class); + example.createCriteria().andLike("level", "%" + deptId + "%"); + + List deptList = deptMapper.selectByExample(example); + + ArrayList deptIds = Lists.newArrayList(); + + if (deptList != null || deptList.size() > 0) { + for (MybatisShiroDept dept : deptList) { + deptIds.add(dept.getId()); + } + } + + return deptIds; + } + + @Override + public List getParentDeptIds(Integer deptId) { + MybatisShiroDept dept = deptMapper.selectByPrimaryKey(deptId); + String level = dept.getLevel(); + ArrayList parentIds = Lists.newArrayList(); + for (String parentId : level.split(COMMA)) { + parentIds.add(Integer.valueOf(parentId)); + } + return parentIds; + } +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroAclMapper.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroAclMapper.java new file mode 100644 index 0000000..cff068b --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroAclMapper.java @@ -0,0 +1,18 @@ +package com.xkcoding.springbootdemorabcshiromybatis.dao; + +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroAcl; +import com.xkcoding.springbootdemorabcshiromybatis.util.MyMapper; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public interface MybatisShiroAclMapper extends MyMapper { + /** + * 根据角色id获取权限列表 + * + * @param roleId 角色id + * @return 权限列表 + */ + List getResUrlsByRoleId(Integer roleId); +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroDeptMapper.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroDeptMapper.java new file mode 100644 index 0000000..9ae8d9a --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroDeptMapper.java @@ -0,0 +1,9 @@ +package com.xkcoding.springbootdemorabcshiromybatis.dao; + +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroDept; +import com.xkcoding.springbootdemorabcshiromybatis.util.MyMapper; +import org.springframework.stereotype.Component; + +@Component +public interface MybatisShiroDeptMapper extends MyMapper { +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroLogMapper.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroLogMapper.java new file mode 100644 index 0000000..2003b20 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroLogMapper.java @@ -0,0 +1,9 @@ +package com.xkcoding.springbootdemorabcshiromybatis.dao; + +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroLog; +import com.xkcoding.springbootdemorabcshiromybatis.util.MyMapper; +import org.springframework.stereotype.Component; + +@Component +public interface MybatisShiroLogMapper extends MyMapper { +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroRoleAclMapper.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroRoleAclMapper.java new file mode 100644 index 0000000..d7ce932 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroRoleAclMapper.java @@ -0,0 +1,9 @@ +package com.xkcoding.springbootdemorabcshiromybatis.dao; + +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroRoleAcl; +import com.xkcoding.springbootdemorabcshiromybatis.util.MyMapper; +import org.springframework.stereotype.Component; + +@Component +public interface MybatisShiroRoleAclMapper extends MyMapper { +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroRoleMapper.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroRoleMapper.java new file mode 100644 index 0000000..f76f18c --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroRoleMapper.java @@ -0,0 +1,9 @@ +package com.xkcoding.springbootdemorabcshiromybatis.dao; + +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroRole; +import com.xkcoding.springbootdemorabcshiromybatis.util.MyMapper; +import org.springframework.stereotype.Component; + +@Component +public interface MybatisShiroRoleMapper extends MyMapper { +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroRoleUserMapper.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroRoleUserMapper.java new file mode 100644 index 0000000..6e8bed2 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroRoleUserMapper.java @@ -0,0 +1,9 @@ +package com.xkcoding.springbootdemorabcshiromybatis.dao; + +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroRoleUser; +import com.xkcoding.springbootdemorabcshiromybatis.util.MyMapper; +import org.springframework.stereotype.Component; + +@Component +public interface MybatisShiroRoleUserMapper extends MyMapper { +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroUserMapper.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroUserMapper.java new file mode 100644 index 0000000..b9e27b0 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/dao/MybatisShiroUserMapper.java @@ -0,0 +1,16 @@ +package com.xkcoding.springbootdemorabcshiromybatis.dao; + +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroUser; +import com.xkcoding.springbootdemorabcshiromybatis.util.MyMapper; +import org.springframework.stereotype.Component; + +@Component +public interface MybatisShiroUserMapper extends MyMapper { + /** + * 根据用户账号获得用户信息 + * + * @param username 用户账号 + * @return 用户对象 + */ + MybatisShiroUser findByUsername(String username); +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/enums/AclStatusEnum.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/enums/AclStatusEnum.java new file mode 100644 index 0000000..68a834e --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/enums/AclStatusEnum.java @@ -0,0 +1,48 @@ +package com.xkcoding.springbootdemorabcshiromybatis.enums; + +import lombok.Getter; + +/** + *

+ * 权限状态的枚举类 + *

+ * + * @package: com.xkcoding.springbootdemorabcshiromybatis.enums + * @description: 权限状态的枚举类 + * @author: yangkai.shen + * @date: Created in 2017/12/6 下午3:38 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +@Getter +public enum AclStatusEnum { + DISABLE(0, "禁用"), ENABLE(1, "启用"); + + private Integer code; + private String message; + + AclStatusEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + /** + * 根据状态码返回状态 + * + * @param code 状态码 + * @return 状态 + */ + public static String valueOf(Integer code) { + if (code == null) { + return null; + } else { + for (AclStatusEnum statusEnum : AclStatusEnum.values()) { + if (statusEnum.getCode().equals(code)) { + return statusEnum.getMessage(); + } + } + return null; + } + } +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/enums/UserStatusEnum.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/enums/UserStatusEnum.java new file mode 100644 index 0000000..27f1a28 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/enums/UserStatusEnum.java @@ -0,0 +1,48 @@ +package com.xkcoding.springbootdemorabcshiromybatis.enums; + +import lombok.Getter; + +/** + *

+ * 用户状态的枚举类 + *

+ * + * @package: com.xkcoding.springbootdemorabcshiromybatis.enums + * @description: 用户状态的枚举类 + * @author: yangkai.shen + * @date: Created in 2017/12/6 下午3:38 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +@Getter +public enum UserStatusEnum { + DELETED(-1, "已删除"), DISABLE(0, "禁用"), ENABLE(1, "启用"); + + private Integer code; + private String message; + + UserStatusEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + /** + * 根据状态码返回状态 + * + * @param code 状态码 + * @return 状态 + */ + public static String valueOf(Integer code) { + if (code == null) { + return null; + } else { + for (UserStatusEnum statusEnum : UserStatusEnum.values()) { + if (statusEnum.getCode().equals(code)) { + return statusEnum.getMessage(); + } + } + return null; + } + } +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroAcl.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroAcl.java new file mode 100644 index 0000000..70d2a5c --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroAcl.java @@ -0,0 +1,334 @@ +package com.xkcoding.springbootdemorabcshiromybatis.model; + +import java.util.Date; +import javax.persistence.*; + +@Table(name = "mybatis_shiro_acl") +public class MybatisShiroAcl { + /** + * 权限id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + /** + * 权限编号 + */ + private String code; + + /** + * 权限名称 + */ + private String name; + + /** + * 权限图标 + */ + private String icon; + + /** + * 上级权限id + */ + @Column(name = "parent_id") + private Integer parentId; + + /** + * 权限层级,默认为0,层级直接用逗号(半角)隔开 + */ + private String level; + + /** + * 权限的url, 可以填正则表达式 + */ + private String url; + + /** + * 类型,1:菜单,2:按钮,3:其他 + */ + private Integer type; + + /** + * 状态,0:冻结,1:正常 + */ + private Integer status; + + /** + * 权限在当前层级下的顺序,由小到大 + */ + private Integer seq; + + /** + * 备注 + */ + private String remark; + + /** + * 操作者 + */ + private String operator; + + /** + * 最后一次更新时间 + */ + @Column(name = "operate_time") + private Date operateTime; + + /** + * 最后一次更新操作者的ip地址 + */ + @Column(name = "operate_ip") + private String operateIp; + + /** + * 获取权限id + * + * @return id - 权限id + */ + public Integer getId() { + return id; + } + + /** + * 设置权限id + * + * @param id 权限id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取权限编号 + * + * @return code - 权限编号 + */ + public String getCode() { + return code; + } + + /** + * 设置权限编号 + * + * @param code 权限编号 + */ + public void setCode(String code) { + this.code = code; + } + + /** + * 获取权限名称 + * + * @return name - 权限名称 + */ + public String getName() { + return name; + } + + /** + * 设置权限名称 + * + * @param name 权限名称 + */ + public void setName(String name) { + this.name = name; + } + + /** + * 获取权限图标 + * + * @return icon - 权限图标 + */ + public String getIcon() { + return icon; + } + + /** + * 设置权限图标 + * + * @param icon 权限图标 + */ + public void setIcon(String icon) { + this.icon = icon; + } + + /** + * 获取上级权限id + * + * @return parent_id - 上级权限id + */ + public Integer getParentId() { + return parentId; + } + + /** + * 设置上级权限id + * + * @param parentId 上级权限id + */ + public void setParentId(Integer parentId) { + this.parentId = parentId; + } + + /** + * 获取权限层级,默认为0,层级直接用逗号(半角)隔开 + * + * @return level - 权限层级,默认为0,层级直接用逗号(半角)隔开 + */ + public String getLevel() { + return level; + } + + /** + * 设置权限层级,默认为0,层级直接用逗号(半角)隔开 + * + * @param level 权限层级,默认为0,层级直接用逗号(半角)隔开 + */ + public void setLevel(String level) { + this.level = level; + } + + /** + * 获取权限的url, 可以填正则表达式 + * + * @return url - 权限的url, 可以填正则表达式 + */ + public String getUrl() { + return url; + } + + /** + * 设置权限的url, 可以填正则表达式 + * + * @param url 权限的url, 可以填正则表达式 + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * 获取类型,1:菜单,2:按钮,3:其他 + * + * @return type - 类型,1:菜单,2:按钮,3:其他 + */ + public Integer getType() { + return type; + } + + /** + * 设置类型,1:菜单,2:按钮,3:其他 + * + * @param type 类型,1:菜单,2:按钮,3:其他 + */ + public void setType(Integer type) { + this.type = type; + } + + /** + * 获取状态,0:冻结,1:正常 + * + * @return status - 状态,0:冻结,1:正常 + */ + public Integer getStatus() { + return status; + } + + /** + * 设置状态,0:冻结,1:正常 + * + * @param status 状态,0:冻结,1:正常 + */ + public void setStatus(Integer status) { + this.status = status; + } + + /** + * 获取权限在当前层级下的顺序,由小到大 + * + * @return seq - 权限在当前层级下的顺序,由小到大 + */ + public Integer getSeq() { + return seq; + } + + /** + * 设置权限在当前层级下的顺序,由小到大 + * + * @param seq 权限在当前层级下的顺序,由小到大 + */ + public void setSeq(Integer seq) { + this.seq = seq; + } + + /** + * 获取备注 + * + * @return remark - 备注 + */ + public String getRemark() { + return remark; + } + + /** + * 设置备注 + * + * @param remark 备注 + */ + public void setRemark(String remark) { + this.remark = remark; + } + + /** + * 获取操作者 + * + * @return operator - 操作者 + */ + public String getOperator() { + return operator; + } + + /** + * 设置操作者 + * + * @param operator 操作者 + */ + public void setOperator(String operator) { + this.operator = operator; + } + + /** + * 获取最后一次更新时间 + * + * @return operate_time - 最后一次更新时间 + */ + public Date getOperateTime() { + return operateTime; + } + + /** + * 设置最后一次更新时间 + * + * @param operateTime 最后一次更新时间 + */ + public void setOperateTime(Date operateTime) { + this.operateTime = operateTime; + } + + /** + * 获取最后一次更新操作者的ip地址 + * + * @return operate_ip - 最后一次更新操作者的ip地址 + */ + public String getOperateIp() { + return operateIp; + } + + /** + * 设置最后一次更新操作者的ip地址 + * + * @param operateIp 最后一次更新操作者的ip地址 + */ + public void setOperateIp(String operateIp) { + this.operateIp = operateIp; + } +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroDept.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroDept.java new file mode 100644 index 0000000..27c9c34 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroDept.java @@ -0,0 +1,219 @@ +package com.xkcoding.springbootdemorabcshiromybatis.model; + +import java.util.Date; +import javax.persistence.*; + +@Table(name = "mybatis_shiro_dept") +public class MybatisShiroDept { + /** + * 部门id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + /** + * 部门名称 + */ + private String name; + + /** + * 上级部门id,顶层是0 + */ + @Column(name = "parent_id") + private Integer parentId; + + /** + * 部门层级,默认为0,层级直接用逗号(半角)隔开 + */ + private String level; + + /** + * 部门在当前层级下的顺序,由小到大 + */ + private Integer seq; + + /** + * 备注 + */ + private String remark; + + /** + * 操作者 + */ + private String operator; + + /** + * 最后一次更新时间 + */ + @Column(name = "operate_time") + private Date operateTime; + + /** + * 最后一次更新操作者的ip地址 + */ + @Column(name = "operate_ip") + private String operateIp; + + /** + * 获取部门id + * + * @return id - 部门id + */ + public Integer getId() { + return id; + } + + /** + * 设置部门id + * + * @param id 部门id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取部门名称 + * + * @return name - 部门名称 + */ + public String getName() { + return name; + } + + /** + * 设置部门名称 + * + * @param name 部门名称 + */ + public void setName(String name) { + this.name = name; + } + + /** + * 获取上级部门id,顶层是0 + * + * @return parent_id - 上级部门id,顶层是0 + */ + public Integer getParentId() { + return parentId; + } + + /** + * 设置上级部门id,顶层是0 + * + * @param parentId 上级部门id,顶层是0 + */ + public void setParentId(Integer parentId) { + this.parentId = parentId; + } + + /** + * 获取部门层级,默认为0,层级直接用逗号(半角)隔开 + * + * @return level - 部门层级,默认为0,层级直接用逗号(半角)隔开 + */ + public String getLevel() { + return level; + } + + /** + * 设置部门层级,默认为0,层级直接用逗号(半角)隔开 + * + * @param level 部门层级,默认为0,层级直接用逗号(半角)隔开 + */ + public void setLevel(String level) { + this.level = level; + } + + /** + * 获取部门在当前层级下的顺序,由小到大 + * + * @return seq - 部门在当前层级下的顺序,由小到大 + */ + public Integer getSeq() { + return seq; + } + + /** + * 设置部门在当前层级下的顺序,由小到大 + * + * @param seq 部门在当前层级下的顺序,由小到大 + */ + public void setSeq(Integer seq) { + this.seq = seq; + } + + /** + * 获取备注 + * + * @return remark - 备注 + */ + public String getRemark() { + return remark; + } + + /** + * 设置备注 + * + * @param remark 备注 + */ + public void setRemark(String remark) { + this.remark = remark; + } + + /** + * 获取操作者 + * + * @return operator - 操作者 + */ + public String getOperator() { + return operator; + } + + /** + * 设置操作者 + * + * @param operator 操作者 + */ + public void setOperator(String operator) { + this.operator = operator; + } + + /** + * 获取最后一次更新时间 + * + * @return operate_time - 最后一次更新时间 + */ + public Date getOperateTime() { + return operateTime; + } + + /** + * 设置最后一次更新时间 + * + * @param operateTime 最后一次更新时间 + */ + public void setOperateTime(Date operateTime) { + this.operateTime = operateTime; + } + + /** + * 获取最后一次更新操作者的ip地址 + * + * @return operate_ip - 最后一次更新操作者的ip地址 + */ + public String getOperateIp() { + return operateIp; + } + + /** + * 设置最后一次更新操作者的ip地址 + * + * @param operateIp 最后一次更新操作者的ip地址 + */ + public void setOperateIp(String operateIp) { + this.operateIp = operateIp; + } +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroLog.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroLog.java new file mode 100644 index 0000000..e0826e3 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroLog.java @@ -0,0 +1,221 @@ +package com.xkcoding.springbootdemorabcshiromybatis.model; + +import java.util.Date; +import javax.persistence.*; + +@Table(name = "mybatis_shiro_log") +public class MybatisShiroLog { + /** + * 日志记录id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + /** + * 权限更新的类型,1:部门,2:用户,3:权限模块,4:权限,5:角色,6:角色用户关系,7:角色权限关系 + */ + private Integer type; + + /** + * 基于type后指定的对象id,比如用户、权限、角色等表的主键 + */ + @Column(name = "target_id") + private Integer targetId; + + /** + * 操作者 + */ + private String operator; + + /** + * 最后一次更新时间 + */ + @Column(name = "operate_time") + private Date operateTime; + + /** + * 最后一次更新操作者的ip地址 + */ + @Column(name = "operate_ip") + private String operateIp; + + /** + * 当前是否复原过,0:没有复原过,1:复原过 + */ + private Integer status; + + /** + * 旧值 + */ + @Column(name = "old_value") + private String oldValue; + + /** + * 新值 + */ + @Column(name = "new_value") + private String newValue; + + /** + * 获取日志记录id + * + * @return id - 日志记录id + */ + public Integer getId() { + return id; + } + + /** + * 设置日志记录id + * + * @param id 日志记录id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取权限更新的类型,1:部门,2:用户,3:权限模块,4:权限,5:角色,6:角色用户关系,7:角色权限关系 + * + * @return type - 权限更新的类型,1:部门,2:用户,3:权限模块,4:权限,5:角色,6:角色用户关系,7:角色权限关系 + */ + public Integer getType() { + return type; + } + + /** + * 设置权限更新的类型,1:部门,2:用户,3:权限模块,4:权限,5:角色,6:角色用户关系,7:角色权限关系 + * + * @param type 权限更新的类型,1:部门,2:用户,3:权限模块,4:权限,5:角色,6:角色用户关系,7:角色权限关系 + */ + public void setType(Integer type) { + this.type = type; + } + + /** + * 获取基于type后指定的对象id,比如用户、权限、角色等表的主键 + * + * @return target_id - 基于type后指定的对象id,比如用户、权限、角色等表的主键 + */ + public Integer getTargetId() { + return targetId; + } + + /** + * 设置基于type后指定的对象id,比如用户、权限、角色等表的主键 + * + * @param targetId 基于type后指定的对象id,比如用户、权限、角色等表的主键 + */ + public void setTargetId(Integer targetId) { + this.targetId = targetId; + } + + /** + * 获取操作者 + * + * @return operator - 操作者 + */ + public String getOperator() { + return operator; + } + + /** + * 设置操作者 + * + * @param operator 操作者 + */ + public void setOperator(String operator) { + this.operator = operator; + } + + /** + * 获取最后一次更新时间 + * + * @return operate_time - 最后一次更新时间 + */ + public Date getOperateTime() { + return operateTime; + } + + /** + * 设置最后一次更新时间 + * + * @param operateTime 最后一次更新时间 + */ + public void setOperateTime(Date operateTime) { + this.operateTime = operateTime; + } + + /** + * 获取最后一次更新操作者的ip地址 + * + * @return operate_ip - 最后一次更新操作者的ip地址 + */ + public String getOperateIp() { + return operateIp; + } + + /** + * 设置最后一次更新操作者的ip地址 + * + * @param operateIp 最后一次更新操作者的ip地址 + */ + public void setOperateIp(String operateIp) { + this.operateIp = operateIp; + } + + /** + * 获取当前是否复原过,0:没有复原过,1:复原过 + * + * @return status - 当前是否复原过,0:没有复原过,1:复原过 + */ + public Integer getStatus() { + return status; + } + + /** + * 设置当前是否复原过,0:没有复原过,1:复原过 + * + * @param status 当前是否复原过,0:没有复原过,1:复原过 + */ + public void setStatus(Integer status) { + this.status = status; + } + + /** + * 获取旧值 + * + * @return old_value - 旧值 + */ + public String getOldValue() { + return oldValue; + } + + /** + * 设置旧值 + * + * @param oldValue 旧值 + */ + public void setOldValue(String oldValue) { + this.oldValue = oldValue; + } + + /** + * 获取新值 + * + * @return new_value - 新值 + */ + public String getNewValue() { + return newValue; + } + + /** + * 设置新值 + * + * @param newValue 新值 + */ + public void setNewValue(String newValue) { + this.newValue = newValue; + } +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroRole.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroRole.java new file mode 100644 index 0000000..0358321 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroRole.java @@ -0,0 +1,195 @@ +package com.xkcoding.springbootdemorabcshiromybatis.model; + +import java.util.Date; +import javax.persistence.*; + +@Table(name = "mybatis_shiro_role") +public class MybatisShiroRole { + /** + * 角色id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + /** + * 角色名称 + */ + private String name; + + /** + * 角色的类型,1:管理员角色,2:其他 + */ + private Integer type; + + /** + * 状态,0:冻结,1:可用 + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + /** + * 操作者 + */ + private String operator; + + /** + * 最后一次更新时间 + */ + @Column(name = "operate_time") + private Date operateTime; + + /** + * 最后一次更新操作者的ip地址 + */ + @Column(name = "operate_ip") + private String operateIp; + + /** + * 获取角色id + * + * @return id - 角色id + */ + public Integer getId() { + return id; + } + + /** + * 设置角色id + * + * @param id 角色id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取角色名称 + * + * @return name - 角色名称 + */ + public String getName() { + return name; + } + + /** + * 设置角色名称 + * + * @param name 角色名称 + */ + public void setName(String name) { + this.name = name; + } + + /** + * 获取角色的类型,1:管理员角色,2:其他 + * + * @return type - 角色的类型,1:管理员角色,2:其他 + */ + public Integer getType() { + return type; + } + + /** + * 设置角色的类型,1:管理员角色,2:其他 + * + * @param type 角色的类型,1:管理员角色,2:其他 + */ + public void setType(Integer type) { + this.type = type; + } + + /** + * 获取状态,0:冻结,1:可用 + * + * @return status - 状态,0:冻结,1:可用 + */ + public Integer getStatus() { + return status; + } + + /** + * 设置状态,0:冻结,1:可用 + * + * @param status 状态,0:冻结,1:可用 + */ + public void setStatus(Integer status) { + this.status = status; + } + + /** + * 获取备注 + * + * @return remark - 备注 + */ + public String getRemark() { + return remark; + } + + /** + * 设置备注 + * + * @param remark 备注 + */ + public void setRemark(String remark) { + this.remark = remark; + } + + /** + * 获取操作者 + * + * @return operator - 操作者 + */ + public String getOperator() { + return operator; + } + + /** + * 设置操作者 + * + * @param operator 操作者 + */ + public void setOperator(String operator) { + this.operator = operator; + } + + /** + * 获取最后一次更新时间 + * + * @return operate_time - 最后一次更新时间 + */ + public Date getOperateTime() { + return operateTime; + } + + /** + * 设置最后一次更新时间 + * + * @param operateTime 最后一次更新时间 + */ + public void setOperateTime(Date operateTime) { + this.operateTime = operateTime; + } + + /** + * 获取最后一次更新操作者的ip地址 + * + * @return operate_ip - 最后一次更新操作者的ip地址 + */ + public String getOperateIp() { + return operateIp; + } + + /** + * 设置最后一次更新操作者的ip地址 + * + * @param operateIp 最后一次更新操作者的ip地址 + */ + public void setOperateIp(String operateIp) { + this.operateIp = operateIp; + } +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroRoleAcl.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroRoleAcl.java new file mode 100644 index 0000000..aaeab53 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroRoleAcl.java @@ -0,0 +1,151 @@ +package com.xkcoding.springbootdemorabcshiromybatis.model; + +import java.util.Date; +import javax.persistence.*; + +@Table(name = "mybatis_shiro_role_acl") +public class MybatisShiroRoleAcl { + /** + * 角色-权限id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + /** + * 角色id + */ + @Column(name = "role_id") + private Integer roleId; + + /** + * 权限id + */ + @Column(name = "acl_id") + private Integer aclId; + + /** + * 操作者 + */ + private String operator; + + /** + * 最后一次更新时间 + */ + @Column(name = "operate_time") + private Date operateTime; + + /** + * 最后一次更新操作者的ip地址 + */ + @Column(name = "operate_ip") + private String operateIp; + + /** + * 获取角色-权限id + * + * @return id - 角色-权限id + */ + public Integer getId() { + return id; + } + + /** + * 设置角色-权限id + * + * @param id 角色-权限id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取角色id + * + * @return role_id - 角色id + */ + public Integer getRoleId() { + return roleId; + } + + /** + * 设置角色id + * + * @param roleId 角色id + */ + public void setRoleId(Integer roleId) { + this.roleId = roleId; + } + + /** + * 获取权限id + * + * @return acl_id - 权限id + */ + public Integer getAclId() { + return aclId; + } + + /** + * 设置权限id + * + * @param aclId 权限id + */ + public void setAclId(Integer aclId) { + this.aclId = aclId; + } + + /** + * 获取操作者 + * + * @return operator - 操作者 + */ + public String getOperator() { + return operator; + } + + /** + * 设置操作者 + * + * @param operator 操作者 + */ + public void setOperator(String operator) { + this.operator = operator; + } + + /** + * 获取最后一次更新时间 + * + * @return operate_time - 最后一次更新时间 + */ + public Date getOperateTime() { + return operateTime; + } + + /** + * 设置最后一次更新时间 + * + * @param operateTime 最后一次更新时间 + */ + public void setOperateTime(Date operateTime) { + this.operateTime = operateTime; + } + + /** + * 获取最后一次更新操作者的ip地址 + * + * @return operate_ip - 最后一次更新操作者的ip地址 + */ + public String getOperateIp() { + return operateIp; + } + + /** + * 设置最后一次更新操作者的ip地址 + * + * @param operateIp 最后一次更新操作者的ip地址 + */ + public void setOperateIp(String operateIp) { + this.operateIp = operateIp; + } +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroRoleUser.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroRoleUser.java new file mode 100644 index 0000000..1ea2885 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroRoleUser.java @@ -0,0 +1,151 @@ +package com.xkcoding.springbootdemorabcshiromybatis.model; + +import java.util.Date; +import javax.persistence.*; + +@Table(name = "mybatis_shiro_role_user") +public class MybatisShiroRoleUser { + /** + * 角色-用户id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + /** + * 角色id + */ + @Column(name = "role_id") + private Integer roleId; + + /** + * 用户id + */ + @Column(name = "user_id") + private Integer userId; + + /** + * 操作者 + */ + private String operator; + + /** + * 最后一次更新时间 + */ + @Column(name = "operate_time") + private Date operateTime; + + /** + * 最后一次更新操作者的ip地址 + */ + @Column(name = "operate_ip") + private String operateIp; + + /** + * 获取角色-用户id + * + * @return id - 角色-用户id + */ + public Integer getId() { + return id; + } + + /** + * 设置角色-用户id + * + * @param id 角色-用户id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取角色id + * + * @return role_id - 角色id + */ + public Integer getRoleId() { + return roleId; + } + + /** + * 设置角色id + * + * @param roleId 角色id + */ + public void setRoleId(Integer roleId) { + this.roleId = roleId; + } + + /** + * 获取用户id + * + * @return user_id - 用户id + */ + public Integer getUserId() { + return userId; + } + + /** + * 设置用户id + * + * @param userId 用户id + */ + public void setUserId(Integer userId) { + this.userId = userId; + } + + /** + * 获取操作者 + * + * @return operator - 操作者 + */ + public String getOperator() { + return operator; + } + + /** + * 设置操作者 + * + * @param operator 操作者 + */ + public void setOperator(String operator) { + this.operator = operator; + } + + /** + * 获取最后一次更新时间 + * + * @return operate_time - 最后一次更新时间 + */ + public Date getOperateTime() { + return operateTime; + } + + /** + * 设置最后一次更新时间 + * + * @param operateTime 最后一次更新时间 + */ + public void setOperateTime(Date operateTime) { + this.operateTime = operateTime; + } + + /** + * 获取最后一次更新操作者的ip地址 + * + * @return operate_ip - 最后一次更新操作者的ip地址 + */ + public String getOperateIp() { + return operateIp; + } + + /** + * 设置最后一次更新操作者的ip地址 + * + * @param operateIp 最后一次更新操作者的ip地址 + */ + public void setOperateIp(String operateIp) { + this.operateIp = operateIp; + } +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroUser.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroUser.java new file mode 100644 index 0000000..4317b07 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/model/MybatisShiroUser.java @@ -0,0 +1,382 @@ +package com.xkcoding.springbootdemorabcshiromybatis.model; + +import java.util.Date; +import javax.persistence.*; + +@Table(name = "mybatis_shiro_user") +public class MybatisShiroUser { + /** + * 用户id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + /** + * 用户名 + */ + private String username; + + /** + * 加密后的密码 + */ + private String password; + + /** + * 密码加密的盐值 + */ + private String salt; + + /** + * 头像 + */ + private String avatar; + + /** + * 真实姓名 + */ + private String realname; + + /** + * 手机号 + */ + private String telephone; + + /** + * 邮箱 + */ + private String mail; + + /** + * 用户所在部门的id + */ + @Column(name = "dept_id") + private Integer deptId; + + /** + * 状态,-1:删除,0:冻结状态,1:正常 + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + /** + * 最后一次登录的时间 + */ + @Column(name = "last_time") + private Date lastTime; + + /** + * 最后一次登录的ip地址 + */ + @Column(name = "last_ip") + private String lastIp; + + /** + * 操作者 + */ + private String operator; + + /** + * 最后一次更新时间 + */ + @Column(name = "operate_time") + private Date operateTime; + + /** + * 最后一次更新操作者的ip地址 + */ + @Column(name = "operate_ip") + private String operateIp; + + /** + * 获取用户id + * + * @return id - 用户id + */ + public Integer getId() { + return id; + } + + /** + * 设置用户id + * + * @param id 用户id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * 获取用户名 + * + * @return username - 用户名 + */ + public String getUsername() { + return username; + } + + /** + * 设置用户名 + * + * @param username 用户名 + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * 获取加密后的密码 + * + * @return password - 加密后的密码 + */ + public String getPassword() { + return password; + } + + /** + * 设置加密后的密码 + * + * @param password 加密后的密码 + */ + public void setPassword(String password) { + this.password = password; + } + + /** + * 获取密码加密的盐值 + * + * @return salt - 密码加密的盐值 + */ + public String getSalt() { + return salt; + } + + /** + * 设置密码加密的盐值 + * + * @param salt 密码加密的盐值 + */ + public void setSalt(String salt) { + this.salt = salt; + } + + /** + * 获取头像 + * + * @return avatar - 头像 + */ + public String getAvatar() { + return avatar; + } + + /** + * 设置头像 + * + * @param avatar 头像 + */ + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + /** + * 获取真实姓名 + * + * @return realname - 真实姓名 + */ + public String getRealname() { + return realname; + } + + /** + * 设置真实姓名 + * + * @param realname 真实姓名 + */ + public void setRealname(String realname) { + this.realname = realname; + } + + /** + * 获取手机号 + * + * @return telephone - 手机号 + */ + public String getTelephone() { + return telephone; + } + + /** + * 设置手机号 + * + * @param telephone 手机号 + */ + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + /** + * 获取邮箱 + * + * @return mail - 邮箱 + */ + public String getMail() { + return mail; + } + + /** + * 设置邮箱 + * + * @param mail 邮箱 + */ + public void setMail(String mail) { + this.mail = mail; + } + + /** + * 获取用户所在部门的id + * + * @return dept_id - 用户所在部门的id + */ + public Integer getDeptId() { + return deptId; + } + + /** + * 设置用户所在部门的id + * + * @param deptId 用户所在部门的id + */ + public void setDeptId(Integer deptId) { + this.deptId = deptId; + } + + /** + * 获取状态,-1:删除,0:冻结状态,1:正常 + * + * @return status - 状态,-1:删除,0:冻结状态,1:正常 + */ + public Integer getStatus() { + return status; + } + + /** + * 设置状态,-1:删除,0:冻结状态,1:正常 + * + * @param status 状态,-1:删除,0:冻结状态,1:正常 + */ + public void setStatus(Integer status) { + this.status = status; + } + + /** + * 获取备注 + * + * @return remark - 备注 + */ + public String getRemark() { + return remark; + } + + /** + * 设置备注 + * + * @param remark 备注 + */ + public void setRemark(String remark) { + this.remark = remark; + } + + /** + * 获取最后一次登录的时间 + * + * @return last_time - 最后一次登录的时间 + */ + public Date getLastTime() { + return lastTime; + } + + /** + * 设置最后一次登录的时间 + * + * @param lastTime 最后一次登录的时间 + */ + public void setLastTime(Date lastTime) { + this.lastTime = lastTime; + } + + /** + * 获取最后一次登录的ip地址 + * + * @return last_ip - 最后一次登录的ip地址 + */ + public String getLastIp() { + return lastIp; + } + + /** + * 设置最后一次登录的ip地址 + * + * @param lastIp 最后一次登录的ip地址 + */ + public void setLastIp(String lastIp) { + this.lastIp = lastIp; + } + + /** + * 获取操作者 + * + * @return operator - 操作者 + */ + public String getOperator() { + return operator; + } + + /** + * 设置操作者 + * + * @param operator 操作者 + */ + public void setOperator(String operator) { + this.operator = operator; + } + + /** + * 获取最后一次更新时间 + * + * @return operate_time - 最后一次更新时间 + */ + public Date getOperateTime() { + return operateTime; + } + + /** + * 设置最后一次更新时间 + * + * @param operateTime 最后一次更新时间 + */ + public void setOperateTime(Date operateTime) { + this.operateTime = operateTime; + } + + /** + * 获取最后一次更新操作者的ip地址 + * + * @return operate_ip - 最后一次更新操作者的ip地址 + */ + public String getOperateIp() { + return operateIp; + } + + /** + * 设置最后一次更新操作者的ip地址 + * + * @param operateIp 最后一次更新操作者的ip地址 + */ + public void setOperateIp(String operateIp) { + this.operateIp = operateIp; + } +} \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/MyShiroRealm.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/MyShiroRealm.java new file mode 100644 index 0000000..8ffbb63 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/MyShiroRealm.java @@ -0,0 +1,96 @@ +package com.xkcoding.springbootdemorabcshiromybatis.shiro; + +import com.google.common.collect.Sets; +import com.xiaoleilu.hutool.util.StrUtil; +import com.xkcoding.springbootdemorabcshiromybatis.dao.MybatisShiroUserMapper; +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroUser; +import com.xkcoding.springbootdemorabcshiromybatis.shiro.factory.Shiro; +import com.xkcoding.springbootdemorabcshiromybatis.shiro.factory.ShiroFactroy; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authc.*; +import org.apache.shiro.authc.credential.CredentialsMatcher; +import org.apache.shiro.authc.credential.HashedCredentialsMatcher; +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 java.util.List; +import java.util.Set; + +/** + * shiro 身份校验 + * + * @package: com.xkcoding.springbootdemorabcshiromybatis.shiro + * @description: shiro 身份校验 + * @author: yangkai.shen + * @date: Created in 2017/11/29 下午3:39 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +@Slf4j +public class MyShiroRealm extends AuthorizingRealm { + @Autowired + private MybatisShiroUserMapper mybatisShiroUserMapper; + + /** + * 身份认证: Authentication 用来验证用户信息 + * + * @param authenticationToken + * @return + * @throws AuthenticationException + */ + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { + log.info("【身份认证】:进入doGetAuthenticationInfo()"); + + Shiro shiroFactory = ShiroFactroy.me(); + UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; + MybatisShiroUser user = shiroFactory.user(token.getUsername()); + ShiroUser shiroUser = shiroFactory.shiroUser(user); + SimpleAuthenticationInfo info = shiroFactory.info(shiroUser, user, super.getName()); + return info; + + } + + /** + * 授权验证 + * + * @param principalCollection + * @return + */ + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { + log.info("【授权验证】:进入doGetAuthorizationInfo()"); + Shiro shiroFactory = ShiroFactroy.me(); + ShiroUser shiroUser = (ShiroUser) principalCollection.getPrimaryPrincipal(); + List roleList = shiroUser.getRoleList(); + + Set aclSet = Sets.newHashSet(); + Set roleNameSet = Sets.newHashSet(shiroUser.getRoleNames()); + + for (Integer roleId : roleList) { + List acls = shiroFactory.findAclsByRoleId(roleId); + for (String acl : acls) { + if (StrUtil.isNotEmpty(acl)) { + aclSet.add(acl); + } + } + } + + SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); + info.addStringPermissions(aclSet); + info.addRoles(roleNameSet); + return info; + } + + @Override + public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { + HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher(); + md5CredentialsMatcher.setHashAlgorithmName(ShiroUtil.HASH_ALGORITHM_NAME); + md5CredentialsMatcher.setHashIterations(ShiroUtil.HASH_ITERATIONS); + super.setCredentialsMatcher(md5CredentialsMatcher); + } +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/ShiroUser.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/ShiroUser.java new file mode 100644 index 0000000..3bb256a --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/ShiroUser.java @@ -0,0 +1,34 @@ +package com.xkcoding.springbootdemorabcshiromybatis.shiro; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + *

+ * 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息 + *

+ * + * @package: com.xkcoding.springbootdemorabcshiromybatis.shiro + * @description: 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息 + * @author: yangkai.shen + * @date: Created in 2017/12/6 下午3:26 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +@Data +public class ShiroUser implements Serializable { + + private static final long serialVersionUID = 1L; + + private Integer id; + private String username; + private String realname; + private Integer deptId; + private String deptName; + private List roleList; + private List roleNames; + +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/ShiroUtil.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/ShiroUtil.java new file mode 100644 index 0000000..eb99f9c --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/ShiroUtil.java @@ -0,0 +1,270 @@ +package com.xkcoding.springbootdemorabcshiromybatis.shiro; + +import com.xkcoding.springbootdemorabcshiromybatis.constrant.factory.Constant; +import com.xkcoding.springbootdemorabcshiromybatis.constrant.factory.ConstantFactory; +import com.xkcoding.util.T; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.crypto.hash.Md5Hash; +import org.apache.shiro.crypto.hash.SimpleHash; +import org.apache.shiro.session.Session; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.util.ByteSource; + +import java.util.List; + +/** + *

+ * shiro 工具类 + *

+ * + * @package: com.xkcoding.springbootdemorabcshiromybatis.shiro + * @description: shiro 工具类 + * @author: yangkai.shen + * @date: Created in 2017/12/1 下午6:02 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +public class ShiroUtil { + + /** + * 加盐参数 + */ + public final static String HASH_ALGORITHM_NAME = "MD5"; + + /** + * 循环次数 + */ + public final static int HASH_ITERATIONS = 1; + + /** + * shiro密码加密工具类 + * + * @param credentials 密码 + * @param saltSource 密码盐 + * @return 加密后的字符串 + */ + public static String md5(String credentials, String saltSource) { + ByteSource salt = new Md5Hash(saltSource); + return new SimpleHash(HASH_ALGORITHM_NAME, credentials, salt, HASH_ITERATIONS).toString(); + } + + /** + * 获取随机盐值 + * + * @return 获取随机盐值 + */ + public static String getRandomSalt() { + return T.UUID(); + } + + /** + * 获取当前 Subject + * + * @return Subject + */ + public static Subject getSubject() { + return SecurityUtils.getSubject(); + } + + /** + * 获取封装的 ShiroUser + * + * @return ShiroUser + */ + public static ShiroUser getUser() { + if (isGuest()) { + return null; + } else { + return (ShiroUser) getSubject().getPrincipals().getPrimaryPrincipal(); + } + } + + /** + * 从shiro获取session + */ + public static Session getSession() { + return getSubject().getSession(); + } + + /** + * 获取shiro指定的sessionKey + */ + @SuppressWarnings("unchecked") + public static T getSessionAttr(String key) { + Session session = getSession(); + return session != null ? (T) session.getAttribute(key) : null; + } + + /** + * 设置shiro指定的sessionKey + */ + public static void setSessionAttr(String key, Object value) { + Session session = getSession(); + session.setAttribute(key, value); + } + + /** + * 移除shiro指定的sessionKey + */ + public static void removeSessionAttr(String key) { + Session session = getSession(); + if (session != null) { + session.removeAttribute(key); + } + } + + /** + * 验证当前用户是否属于该角色?,使用时与lacksRole 搭配使用 + * + * @param roleName 角色名 + * @return 属于该角色:true,否则false + */ + public static boolean hasRole(String roleName) { + return getSubject() != null && roleName != null && roleName.length() > 0 && getSubject().hasRole(roleName); + } + + /** + * 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。 + * + * @param roleName 角色名 + * @return 不属于该角色:true,否则false + */ + public static boolean lacksRole(String roleName) { + return !hasRole(roleName); + } + + /** + * 验证当前用户是否属于以下任意一个角色。 + * + * @param roleNames 角色列表 + * @return 属于:true,否则false + */ + public static boolean hasAnyRoles(String roleNames) { + boolean hasAnyRole = false; + Subject subject = getSubject(); + if (subject != null && roleNames != null && roleNames.length() > 0) { + for (String role : roleNames.split(Constant.COMMA)) { + if (subject.hasRole(role.trim())) { + hasAnyRole = true; + break; + } + } + } + return hasAnyRole; + } + + /** + * 验证当前用户是否属于以下所有角色。 + * + * @param roleNames 角色列表 + * @return 属于:true,否则false + */ + public static boolean hasAllRoles(String roleNames) { + boolean hasAllRole = true; + Subject subject = getSubject(); + if (subject != null && roleNames != null && roleNames.length() > 0) { + for (String role : roleNames.split(Constant.COMMA)) { + if (!subject.hasRole(role.trim())) { + hasAllRole = false; + break; + } + } + } + return hasAllRole; + } + + /** + * 验证当前用户是否拥有指定权限,使用时与lacksPermission 搭配使用 + * + * @param permission 权限名 + * @return 拥有权限:true,否则false + */ + public static boolean hasPermission(String permission) { + return getSubject() != null && permission != null && permission.length() > 0 && getSubject().isPermitted(permission); + } + + /** + * 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。 + * + * @param permission 权限名 + * @return 拥有权限:true,否则false + */ + public static boolean lacksPermission(String permission) { + return !hasPermission(permission); + } + + /** + * 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。与notAuthenticated搭配使用 + * + * @return 通过身份验证:true,否则false + */ + public static boolean isAuthenticated() { + return getSubject() != null && getSubject().isAuthenticated(); + } + + /** + * 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。。 + * + * @return 没有通过身份验证:true,否则false + */ + public static boolean notAuthenticated() { + return !isAuthenticated(); + } + + /** + * 认证通过或已记住的用户。与guset搭配使用。 + * + * @return 用户:true,否则 false + */ + public static boolean isUser() { + return getSubject() != null && getSubject().getPrincipal() != null; + } + + /** + * 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。用user搭配使用 + * + * @return 访客:true,否则false + */ + public static boolean isGuest() { + return !isUser(); + } + + /** + * 输出当前用户信息,通常为登录帐号信息。 + * + * @return 当前用户信息 + */ + public static String principal() { + if (getSubject() != null) { + Object principal = getSubject().getPrincipal(); + return principal.toString(); + } + return ""; + } + + /** + * 获取当前用户的部门数据范围的集合 + */ + public static List getDeptDataScope() { + Integer deptId = getUser().getDeptId(); + List subDeptIds = ConstantFactory.me().getSubDeptId(deptId); + subDeptIds.add(deptId); + return subDeptIds; + } + + /** + * 判断当前用户是否是超级管理员 + */ + public static boolean isAdmin() { + List roleNameList = getUser().getRoleNames(); + for (String roleName : roleNameList) { + if (roleName.equals(Constant.ADMIN_NAME)) { + return true; + } + } + return false; + } + +} + diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/factory/Shiro.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/factory/Shiro.java new file mode 100644 index 0000000..c793dd4 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/factory/Shiro.java @@ -0,0 +1,66 @@ +package com.xkcoding.springbootdemorabcshiromybatis.shiro.factory; + +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroUser; +import com.xkcoding.springbootdemorabcshiromybatis.shiro.ShiroUser; +import org.apache.shiro.authc.SimpleAuthenticationInfo; + +import java.util.List; + +/** + *

+ * 定义 shiro realm 所需数据的接口 + *

+ * + * @package: com.xkcoding.springbootdemorabcshiromybatis.shiro.factory + * @description: 定义 shiro realm 所需数据的接口 + * @author: yangkai.shen + * @date: Created in 2017/12/6 下午3:24 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +public interface Shiro { + + /** + * 根据用户名数据库存储的用户信息 + * + * @param username 用户名 + * @return 数据库存储的用户信息 + */ + MybatisShiroUser user(String username); + + /** + * 根据系统用户获取 shiro 的用户 + * + * @param user 数据库保存的用户 + * @return 自定义的用户对象 + */ + ShiroUser shiroUser(MybatisShiroUser user); + + /** + * 根据角色id获取权限列表 + * + * @param roleId 角色id + * @return 权限列表 + */ + List findAclsByRoleId(Integer roleId); + + /** + * 根据角色id获取角色名称 + * + * @param roleId 角色id + * @return 角色名称 + */ + String findRoleNameByRoleId(Integer roleId); + + /** + * 获取 shiro 的认证信息 + * + * @param shiroUser 自定义返回的 user 对象 + * @param user 数据库保存的 user 对象 + * @param realmName 真实姓名 + * @return shiro的认证信息 + */ + SimpleAuthenticationInfo info(ShiroUser shiroUser, MybatisShiroUser user, String realmName); + +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/factory/ShiroFactroy.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/factory/ShiroFactroy.java new file mode 100644 index 0000000..26dfe64 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/shiro/factory/ShiroFactroy.java @@ -0,0 +1,95 @@ +package com.xkcoding.springbootdemorabcshiromybatis.shiro.factory; + +import com.xkcoding.springbootdemorabcshiromybatis.constrant.factory.ConstantFactory; +import com.xkcoding.springbootdemorabcshiromybatis.dao.MybatisShiroAclMapper; +import com.xkcoding.springbootdemorabcshiromybatis.dao.MybatisShiroUserMapper; +import com.xkcoding.springbootdemorabcshiromybatis.enums.UserStatusEnum; +import com.xkcoding.springbootdemorabcshiromybatis.model.MybatisShiroUser; +import com.xkcoding.springbootdemorabcshiromybatis.shiro.ShiroUser; +import com.xkcoding.springbootdemorabcshiromybatis.util.SpringContextHolder; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authc.CredentialsException; +import org.apache.shiro.authc.DisabledAccountException; +import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.crypto.hash.Md5Hash; +import org.apache.shiro.util.ByteSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.DependsOn; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@DependsOn("springContextHolder") +@Slf4j +public class ShiroFactroy implements Shiro { + + @Autowired + private MybatisShiroUserMapper userMapper; + + @Autowired + private MybatisShiroAclMapper aclMapper; + + public static Shiro me() { + return SpringContextHolder.getBean(Shiro.class); + } + + @Override + public MybatisShiroUser user(String username) { + + MybatisShiroUser user = userMapper.findByUsername(username); + + // 账号不存在 + if (null == user) { + log.error("【登录失败】:账号不存在"); + throw new CredentialsException("账号不存在"); + } + // 账号被冻结 + if (user.getStatus().equals(UserStatusEnum.DISABLE.getCode())) { + log.error("【登录失败】:用户已被冻结"); + throw new DisabledAccountException("登录失败,用户已被冻结"); + } else if (user.getStatus().equals(UserStatusEnum.DELETED.getCode())) { + log.error("【登录失败】:没有该用户"); + throw new DisabledAccountException("登录失败,没有该用户"); + } + return user; + } + + @Override + public ShiroUser shiroUser(MybatisShiroUser user) { + ShiroUser shiroUser = new ShiroUser(); + + shiroUser.setId(user.getId()); + shiroUser.setUsername(user.getUsername()); + shiroUser.setDeptId(user.getDeptId()); + shiroUser.setDeptName(ConstantFactory.me().getDeptName(user.getDeptId())); + shiroUser.setRealname(user.getRealname()); + + List roleList = ConstantFactory.me().getRoleIds(user.getId()); + List roleNameList = ConstantFactory.me().getRoleNames(roleList); + shiroUser.setRoleList(roleList); + shiroUser.setRoleNames(roleNameList); + + return shiroUser; + } + + @Override + public List findAclsByRoleId(Integer roleId) { + return aclMapper.getResUrlsByRoleId(roleId); + } + + @Override + public String findRoleNameByRoleId(Integer roleId) { + return ConstantFactory.me().getRoleName(roleId); + } + + @Override + public SimpleAuthenticationInfo info(ShiroUser shiroUser, MybatisShiroUser user, String realmName) { + String credentials = user.getPassword(); + // 密码加盐处理 + String source = user.getSalt(); + ByteSource credentialsSalt = new Md5Hash(source); + return new SimpleAuthenticationInfo(shiroUser, credentials, credentialsSalt, realmName); + } + +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/util/MyMapper.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/util/MyMapper.java new file mode 100644 index 0000000..bde8aff --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/util/MyMapper.java @@ -0,0 +1,7 @@ +package com.xkcoding.springbootdemorabcshiromybatis.util; + +import tk.mybatis.mapper.common.Mapper; +import tk.mybatis.mapper.common.MySqlMapper; + +public interface MyMapper extends Mapper, MySqlMapper { +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/util/SpringContextHolder.java b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/util/SpringContextHolder.java new file mode 100644 index 0000000..cf84333 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/java/com/xkcoding/springbootdemorabcshiromybatis/util/SpringContextHolder.java @@ -0,0 +1,50 @@ +package com.xkcoding.springbootdemorabcshiromybatis.util; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + *

+ * Spring 的 ApplicationContext 的持有者,可以用静态方法的方式获取 spring 容器中的 bean + *

+ * + * @package: com.xkcoding.springbootdemorabcshiromybatis.util + * @description: Spring 的 ApplicationContext 的持有者,可以用静态方法的方式获取 spring 容器中的 bean + * @author: yangkai.shen + * @date: Created in 2017/12/1 下午3:47 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +@Component +public class SpringContextHolder implements ApplicationContextAware { + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringContextHolder.applicationContext = applicationContext; + } + + public static ApplicationContext getApplicationContext() { + assertApplicationContext(); + return applicationContext; + } + + public static T getBean(String beanName) { + assertApplicationContext(); + return (T) applicationContext.getBean(beanName); + } + + public static T getBean(Class requiredType) { + assertApplicationContext(); + return applicationContext.getBean(requiredType); + } + + private static void assertApplicationContext() { + if (SpringContextHolder.applicationContext == null) { + throw new RuntimeException("applicaitonContext属性为null,请检查是否注入了SpringContextHolder!"); + } + } +} diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/application.yml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/application.yml new file mode 100644 index 0000000..ef4a669 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/application.yml @@ -0,0 +1,70 @@ +server: + port: 8080 + context-path: /demo +spring: + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + datasource: + # 启动时自动运行的 SQL 文件 + schema: classpath:init-sql/shiro.sql + continue-on-error: true + druid: + url: jdbc:mysql://localhost:3306/spring-boot-demo?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false + username: root + password: root + driver-class-name: com.mysql.jdbc.Driver + # 连接池配置 + # 初始化大小,最小,最大 + initialSize: 5 + minIdle: 5 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + # 打开PSCache,并且指定每个连接上PSCache的大小 + poolPreparedStatements: true + maxPoolPreparedStatementPerConnectionSize: 20 + # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 + filters: stat,wall,log4j + # 监控配置 + web-stat-filter: + enabled: true + url-pattern: /* + exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" + stat-view-servlet: + enabled: true + url-pattern: /sys/druid/* + reset-enable: fasle + login-username: xkcoding + login-password: 123456 + filter: + stat: + log-slow-sql: true + slow-sql-millis: 5000 + merge-sql: true +# mybatis 配置 +mybatis: + type-aliases-package: com.xkcoding.springbootdemoormmybatistis.model + mapper-locations: classpath:mapper/*.xml + # 配置项:开启下划线到驼峰的自动转换. 作用:将数据库字段根据驼峰规则自动注入到对象属性 + configuration: + map-underscore-to-camel-case: true +# 通用 Mapper 配置 +mapper: + not-empty: false + identity: MYSQL + mappers: com.xkcoding.springbootdemorabcshiromybatis.util.MyMapper +# PageHelper 配置 +pagehelper: + helper-dialect: mysql + reasonable: true + support-methods-arguments: true + params: count=countSql \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/generator/config.properties b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/generator/config.properties new file mode 100644 index 0000000..039f8f7 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/generator/config.properties @@ -0,0 +1,8 @@ +# 数据库配置 +jdbc.driverClass=com.mysql.jdbc.Driver +jdbc.url=jdbc:mysql://localhost:3306/spring-boot-demo +jdbc.user=root +jdbc.password=root +# 通用Mapper配置 +mapper.plugin=tk.mybatis.mapper.generator.MapperPlugin +mapper.Mapper=com.xkcoding.springbootdemorabcshiromybatis.util.MyMapper \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/generator/generatorConfig.xml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/generator/generatorConfig.xml new file mode 100644 index 0000000..702b499 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/generator/generatorConfig.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
\ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/init-sql/shiro.sql b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/init-sql/shiro.sql new file mode 100644 index 0000000..881ec4a --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/init-sql/shiro.sql @@ -0,0 +1,141 @@ +-- 建表 -- +-- 部门表 -- +DROP TABLE IF EXISTS `mybatis_shiro_dept`; +CREATE TABLE `mybatis_shiro_dept` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门id', + `name` varchar(20) NOT NULL DEFAULT '' COMMENT '部门名称', + `parent_id` int(11) NOT NULL DEFAULT '0' COMMENT '上级部门id,顶层是0', + `level` varchar(255) NOT NULL DEFAULT '0' COMMENT '部门层级,默认为0,层级直接用逗号(半角)隔开', + `seq` int(11) NOT NULL DEFAULT '0' COMMENT '部门在当前层级下的顺序,由小到大', + `remark` varchar(200) DEFAULT '' COMMENT '备注', + `operator` varchar(20) NOT NULL DEFAULT '' COMMENT '操作者', + `operate_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次更新时间', + `operate_ip` varchar(20) NOT NULL DEFAULT '' COMMENT '最后一次更新操作者的ip地址', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='部门表'; + +INSERT INTO `mybatis_shiro_dept` VALUES (1, '总公司', 0, '0', 0, '总公司', '系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_dept` VALUES (2, '开发部', 1, '0,1', 0, '开发部', '系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_dept` VALUES (3, '运营部', 1, '0,1', 1, '运营部', '系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_dept` VALUES (4, '战略部', 1, '0,1', 2, '战略部', '系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_dept` VALUES (5, '软件部', 2, '0,1,2', 0, '软件部', '系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_dept` VALUES (6, '硬件部', 2, '0,1,2', 1, '硬件部', '系统', '2017-12-01 00:00:00', '127.0.0.1'); + +-- 用户表 -- +DROP TABLE IF EXISTS `mybatis_shiro_user`; +CREATE TABLE `mybatis_shiro_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id', + `username` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名', + `password` varchar(40) NOT NULL DEFAULT '' COMMENT '加密后的密码', + `salt` varchar(32) NOT NULL DEFAULT '' COMMENT '密码加密的盐值', + `avatar` varchar(255) DEFAULT NULL COMMENT '头像', + `realname` varchar(20) NOT NULL DEFAULT '' COMMENT '真实姓名', + `telephone` varchar(13) NOT NULL DEFAULT '' COMMENT '手机号', + `mail` varchar(20) NOT NULL DEFAULT '' COMMENT '邮箱', + `dept_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户所在部门的id', + `status` int(11) NOT NULL DEFAULT '1' COMMENT '状态,-1:删除,0:冻结状态,1:正常', + `remark` varchar(200) DEFAULT '' COMMENT '备注', + `last_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次登录的时间', + `last_ip` varchar(20) NOT NULL DEFAULT '' COMMENT '最后一次登录的ip地址', + `operator` varchar(20) NOT NULL DEFAULT '' COMMENT '操作者', + `operate_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次更新时间', + `operate_ip` varchar(20) NOT NULL DEFAULT '' COMMENT '最后一次更新操作者的ip地址', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT ='用户表'; + +INSERT INTO `mybatis_shiro_user` VALUES (1, 'xkcoding', '29b97b26be547c8442689bdbe6f1efb9', '77798aa08e914989bb588188cb2c0ad4', '','沈扬凯','18601224166','237497819@qq.com',5,1,'本尊','2017-12-01 00:00:00', '127.0.0.1', '系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_user` VALUES (2, 'test', '29b97b26be547c8442689bdbe6f1efb9', '77798aa08e914989bb588188cb2c0ad4', '','测试用户','18666666666','qaz@qq.com',6,1,'测试用户', '2017-12-01 00:00:00', '127.0.0.1','系统', '2017-12-01 00:00:00', '127.0.0.1'); + +-- 权限表 -- +DROP TABLE IF EXISTS `mybatis_shiro_acl`; +CREATE TABLE `mybatis_shiro_acl` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限id', + `code` varchar(20) NOT NULL DEFAULT '' COMMENT '权限编号', + `name` varchar(20) NOT NULL DEFAULT '' COMMENT '权限名称', + `icon` varchar(255) DEFAULT NULL COMMENT '权限图标', + `parent_id` int(11) NOT NULL DEFAULT '0' COMMENT '上级权限id', + `level` varchar(255) NOT NULL DEFAULT '' COMMENT '权限层级,默认为0,层级直接用逗号(半角)隔开', + `url` varchar(100) NOT NULL DEFAULT '' COMMENT '权限的url, 可以填正则表达式', + `type` int(11) NOT NULL DEFAULT '3' COMMENT '类型,1:菜单,2:按钮,3:其他', + `status` int(11) NOT NULL DEFAULT '1' COMMENT '状态,0:冻结,1:正常', + `seq` int(11) NOT NULL DEFAULT '0' COMMENT '权限在当前层级下的顺序,由小到大', + `remark` varchar(200) DEFAULT '' COMMENT '备注', + `operator` varchar(20) NOT NULL DEFAULT '' COMMENT '操作者', + `operate_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次更新时间', + `operate_ip` varchar(20) NOT NULL DEFAULT '' COMMENT '最后一次更新操作者的ip地址', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT ='权限表'; + +INSERT INTO `mybatis_shiro_acl` VALUES (1,'system_mgr','系统管理','',0,'0','/system_mgr/*',1,1,0,'系统管理', '系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_acl` VALUES (2,'user_mgr','用户管理','',1,'0,1','/system_mgr/user_mgr/*',1,1,0,'用户管理', '系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_acl` VALUES (3,'user_insert','新增用户','',2,'0,1,2','/user/add',2,1,0,'新增用户','系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_acl` VALUES (4,'user_delete','删除用户','',2,'0,1,2','/user/delete',2,1,1,'删除用户','系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_acl` VALUES (5,'user_update','修改用户','',2,'0,1,2','/user/update',2,1,2,'修改用户','系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_acl` VALUES (6,'user_select','查询用户','',2,'0,1,2','/user/select',2,1,3,'查询用户','系统', '2017-12-01 00:00:00', '127.0.0.1'); + +-- 角色表 -- +DROP TABLE IF EXISTS `mybatis_shiro_role`; +CREATE TABLE `mybatis_shiro_role` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色id', + `name` varchar(20) NOT NULL COMMENT '角色名称', + `type` int(11) NOT NULL DEFAULT '1' COMMENT '角色的类型,1:管理员角色,2:其他', + `status` int(11) NOT NULL DEFAULT '1' COMMENT '状态,0:冻结,1:可用', + `remark` varchar(200) DEFAULT '' COMMENT '备注', + `operator` varchar(20) NOT NULL DEFAULT '' COMMENT '操作者', + `operate_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次更新时间', + `operate_ip` varchar(20) NOT NULL DEFAULT '' COMMENT '最后一次更新操作者的ip地址', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT ='角色表'; + +INSERT INTO `mybatis_shiro_role` VALUES (1,'超级管理员', 1, 1,'超级管理员' ,'系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_role` VALUES (2, '临时', 2, 1,'临时','系统', '2017-12-01 00:00:00', '127.0.0.1'); + +-- 角色-用户表 -- +DROP TABLE IF EXISTS `mybatis_shiro_role_user`; +CREATE TABLE `mybatis_shiro_role_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色-用户id', + `role_id` int(11) NOT NULL COMMENT '角色id', + `user_id` int(11) NOT NULL COMMENT '用户id', + `operator` varchar(20) NOT NULL DEFAULT '' COMMENT '操作者', + `operate_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次更新时间', + `operate_ip` varchar(20) NOT NULL DEFAULT '' COMMENT '最后一次更新操作者的ip地址', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `mybatis_shiro_role_user` VALUES (1, 1, 1,'系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_role_user` VALUES (2, 2, 2,'系统', '2017-12-01 00:00:00', '127.0.0.1'); + +-- 角色-权限表 -- +DROP TABLE IF EXISTS `mybatis_shiro_role_acl`; +CREATE TABLE `mybatis_shiro_role_acl` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色-权限id', + `role_id` int(11) NOT NULL COMMENT '角色id', + `acl_id` int(11) NOT NULL COMMENT '权限id', + `operator` varchar(20) NOT NULL DEFAULT '' COMMENT '操作者', + `operate_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次更新时间', + `operate_ip` varchar(20) NOT NULL DEFAULT '' COMMENT '最后一次更新操作者的ip地址', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `mybatis_shiro_role_acl` VALUES (1, 1, 1,'系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_role_acl` VALUES (2, 1, 2,'系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_role_acl` VALUES (3, 1, 3,'系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_role_acl` VALUES (4, 1, 4,'系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_role_acl` VALUES (5, 1, 5,'系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_role_acl` VALUES (6, 1, 6,'系统', '2017-12-01 00:00:00', '127.0.0.1'); +INSERT INTO `mybatis_shiro_role_acl` VALUES (7, 2, 6,'系统', '2017-12-01 00:00:00', '127.0.0.1'); + +-- 日志记录表 -- +DROP TABLE IF EXISTS `mybatis_shiro_log`; +CREATE TABLE `mybatis_shiro_log` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '日志记录id', + `type` int(11) NOT NULL DEFAULT '0' COMMENT '权限更新的类型,1:部门,2:用户,3:权限模块,4:权限,5:角色,6:角色用户关系,7:角色权限关系', + `target_id` int(11) NOT NULL COMMENT '基于type后指定的对象id,比如用户、权限、角色等表的主键', + `old_value` text COMMENT '旧值', + `new_value` text COMMENT '新值', + `operator` varchar(20) NOT NULL DEFAULT '' COMMENT '操作者', + `operate_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次更新时间', + `operate_ip` varchar(20) NOT NULL DEFAULT '' COMMENT '最后一次更新操作者的ip地址', + `status` int(11) NOT NULL DEFAULT '0' COMMENT '当前是否复原过,0:没有复原过,1:复原过', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/logback-spring.xml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..77cf77a --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/logback-spring.xml @@ -0,0 +1,51 @@ + + + + + + + + + 【xkcoding】%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} + + + + + + + + + ${user.dir}/logs/log/spring-boot-demo-rabc-shiro-mybatis.%d.log + + + 【xkcoding】%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n + + + + + + ERROR + ACCEPT + DENY + + + + + ${user.dir}/logs/error/spring-boot-demo-rabc-shiro-mybatis.%d.error + + + 【xkcoding】%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroAclMapper.xml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroAclMapper.xml new file mode 100644 index 0000000..ea67113 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroAclMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroDeptMapper.xml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroDeptMapper.xml new file mode 100644 index 0000000..be1d71c --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroDeptMapper.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroLogMapper.xml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroLogMapper.xml new file mode 100644 index 0000000..c33df40 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroLogMapper.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroRoleAclMapper.xml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroRoleAclMapper.xml new file mode 100644 index 0000000..02170ff --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroRoleAclMapper.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroRoleMapper.xml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroRoleMapper.xml new file mode 100644 index 0000000..bd64e59 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroRoleMapper.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroRoleUserMapper.xml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroRoleUserMapper.xml new file mode 100644 index 0000000..2d4d9d4 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroRoleUserMapper.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroUserMapper.xml b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroUserMapper.xml new file mode 100644 index 0000000..a7998a1 --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/main/resources/mapper/MybatisShiroUserMapper.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-demo-rabc-shiro-mybatis/src/test/java/com/xkcoding/springbootdemorabcshiromybatis/SpringBootDemoRabcShiroMybatisApplicationTests.java b/spring-boot-demo-rabc-shiro-mybatis/src/test/java/com/xkcoding/springbootdemorabcshiromybatis/SpringBootDemoRabcShiroMybatisApplicationTests.java new file mode 100644 index 0000000..96e27ab --- /dev/null +++ b/spring-boot-demo-rabc-shiro-mybatis/src/test/java/com/xkcoding/springbootdemorabcshiromybatis/SpringBootDemoRabcShiroMybatisApplicationTests.java @@ -0,0 +1,16 @@ +package com.xkcoding.springbootdemorabcshiromybatis; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringBootDemoRabcShiroMybatisApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-boot-demo-util/pom.xml b/spring-boot-demo-util/pom.xml new file mode 100644 index 0000000..e7b6ffa --- /dev/null +++ b/spring-boot-demo-util/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + com.xkcoding + spring-boot-demo-util + 0.0.1-SNAPSHOT + jar + + + + com.xiaoleilu + hutool-all + 3.2.0 + + + com.google.guava + guava + 20.0 + + + org.projectlombok + lombok + 1.16.18 + + + + + spring-boot-demo-util + + + \ No newline at end of file diff --git a/spring-boot-demo-util/src/main/java/com/xkcoding/util/PingyinUtil.java b/spring-boot-demo-util/src/main/java/com/xkcoding/util/PingyinUtil.java new file mode 100644 index 0000000..fa2ffac --- /dev/null +++ b/spring-boot-demo-util/src/main/java/com/xkcoding/util/PingyinUtil.java @@ -0,0 +1,127 @@ +package com.xkcoding.util; + +import java.util.Random; + +/** + *

+ * 得到中文首字母 + *

+ * + * @package: com.xkcoding.util + * @description: 得到中文首字母 + * @author: yangkai.shen + * @date: Created in 2017/12/1 下午3:52 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +public class PingyinUtil { + public static void main(String[] args) { + String str = "我是一串中文"; + System.out.println("我是一串中文:" + getPYIndexStr(str, true)); + } + + /** + * 返回首字母 + * + * @param strChinese 中文字符串 + * @param bUpCase 是否为大写 + * @return 中文字符串的首字母 + */ + public static String getPYIndexStr(String strChinese, boolean bUpCase) { + try { + StringBuffer buffer = new StringBuffer(); + // 把中文转化成byte数组 + byte b[] = strChinese.getBytes("GBK"); + for (int i = 0; i < b.length; i++) { + if ((b[i] & 255) > 128) { + int char1 = b[i++] & 255; + // 左移运算符用“<<”表示,是将运算符左边的对象,向左移动运算符右边指定的位数,并且在低位补零。其实,向左移n位,就相当于乘上2的n次方 + char1 <<= 8; + int chart = char1 + (b[i] & 255); + buffer.append(getPYIndexChar((char) chart, bUpCase)); + continue; + } + char c = (char) b[i]; + // 确定指定字符是否可以是 Java + if (!Character.isJavaIdentifierPart(c)) { + // 标识符中首字符以外的部分。 + c = 'A'; + } + buffer.append(c); + } + return buffer.toString(); + } catch (Exception e) { + System.out.println((new StringBuilder()).append("\u53D6\u4E2D\u6587\u62FC\u97F3\u6709\u9519").append(e.getMessage()).toString()); + } + return null; + } + + /** + * 得到首字母 + * + * @param strChinese 中文字符 + * @param bUpCase 是否大写 + * @return 中文字符的首字母 + */ + private static char getPYIndexChar(char strChinese, boolean bUpCase) { + + int charGBK = strChinese; + + char result; + + if (charGBK >= 45217 && charGBK <= 45252) { + result = 'A'; + } else if (charGBK >= 45253 && charGBK <= 45760) { + result = 'B'; + } else if (charGBK >= 45761 && charGBK <= 46317) { + result = 'C'; + } else if (charGBK >= 46318 && charGBK <= 46825) { + result = 'D'; + } else if (charGBK >= 46826 && charGBK <= 47009) { + result = 'E'; + } else if (charGBK >= 47010 && charGBK <= 47296) { + result = 'F'; + } else if (charGBK >= 47297 && charGBK <= 47613) { + result = 'G'; + } else if (charGBK >= 47614 && charGBK <= 48118) { + result = 'H'; + } else if (charGBK >= 48119 && charGBK <= 49061) { + result = 'J'; + } else if (charGBK >= 49062 && charGBK <= 49323) { + result = 'K'; + } else if (charGBK >= 49324 && charGBK <= 49895) { + result = 'L'; + } else if (charGBK >= 49896 && charGBK <= 50370) { + result = 'M'; + } else if (charGBK >= 50371 && charGBK <= 50613) { + result = 'N'; + } else if (charGBK >= 50614 && charGBK <= 50621) { + result = 'O'; + } else if (charGBK >= 50622 && charGBK <= 50905) { + result = 'P'; + } else if (charGBK >= 50906 && charGBK <= 51386) { + result = 'Q'; + } else if (charGBK >= 51387 && charGBK <= 51445) { + result = 'R'; + } else if (charGBK >= 51446 && charGBK <= 52217) { + result = 'S'; + } else if (charGBK >= 52218 && charGBK <= 52697) { + result = 'T'; + } else if (charGBK >= 52698 && charGBK <= 52979) { + result = 'W'; + } else if (charGBK >= 52980 && charGBK <= 53688) { + result = 'X'; + } else if (charGBK >= 53689 && charGBK <= 54480) { + result = 'Y'; + } else if (charGBK >= 54481 && charGBK <= 55289) { + result = 'Z'; + } else { + result = (char) (65 + (new Random()).nextInt(25)); + } + if (!bUpCase) { + result = Character.toLowerCase(result); + } + return result; + } +} diff --git a/spring-boot-demo-util/src/main/java/com/xkcoding/util/T.java b/spring-boot-demo-util/src/main/java/com/xkcoding/util/T.java new file mode 100644 index 0000000..95d783b --- /dev/null +++ b/spring-boot-demo-util/src/main/java/com/xkcoding/util/T.java @@ -0,0 +1,63 @@ +package com.xkcoding.util; + +import com.google.common.collect.Maps; +import com.sun.istack.internal.NotNull; +import com.xiaoleilu.hutool.http.HttpUtil; +import com.xiaoleilu.hutool.json.JSONObject; +import com.xiaoleilu.hutool.json.JSONUtil; +import com.xiaoleilu.hutool.util.RandomUtil; +import com.xiaoleilu.hutool.util.StrUtil; +import com.xkcoding.util.domain.ShortUrlRet; + +import java.util.Map; + +/** + *

+ * 高频工具类 + *

+ * + * @package: com.xkcoding.util + * @description: 高频工具类 + * @author: yangkai.shen + * @date: Created in 2017/12/1 下午4:24 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +public class T { + private static final String URL_SEPARATOR = "//"; + private static final String URL_PROTOCOL = "http"; + + /** + * 获取 UUID + * + * @return 返回没有“-”的 UUID + */ + public static String UUID() { + return RandomUtil.randomUUID().replace("-", ""); + } + + /** + * 长地址转短地址 + * + * @param longUrl 长地址 + * @return 长地址转化后的短地址 + */ + public static String shortURL(@NotNull String longUrl) { + Map params = Maps.newHashMap(); + if (StrUtil.isEmpty(longUrl)) { + return null; + } + if (!longUrl.contains(URL_SEPARATOR)) { + longUrl = URL_PROTOCOL + ":" + URL_SEPARATOR + longUrl; + } + params.put("url", longUrl); + params.put("email", "ws@parg.co"); + params.put("api_key", "4786a32f20f79a70b1ced1bf242a120e"); + String data = HttpUtil.post("https://parg.co/api/shorten", params); + JSONObject ret = JSONUtil.parseObj(data); + ShortUrlRet shortUrlRet = ret.toBean(ShortUrlRet.class); + return shortUrlRet.getShort_url(); + } + +} diff --git a/spring-boot-demo-util/src/main/java/com/xkcoding/util/domain/ShortUrlRet.java b/spring-boot-demo-util/src/main/java/com/xkcoding/util/domain/ShortUrlRet.java new file mode 100644 index 0000000..2f2dd37 --- /dev/null +++ b/spring-boot-demo-util/src/main/java/com/xkcoding/util/domain/ShortUrlRet.java @@ -0,0 +1,24 @@ +package com.xkcoding.util.domain; + +import lombok.Data; + +/** + *

+ * 短地址请求返回类型 + *

+ * + * @package: com.xkcoding.util.domain + * @description: 短地址请求返回类型 + * @author: yangkai.shen + * @date: Created in 2017/12/4 上午11:29 + * @copyright: Copyright (c) 2017 + * @version: 0.0.1 + * @modified: yangkai.shen + */ +@Data +public class ShortUrlRet { + private String short_url; + private String long_encoded; + private String long_decoded; + private String status; +}