在上一篇博文中,通过ssm+shiro,可以实现对页面的访问控制,user:"zhang3"角色是"admin",但是没有给他分配"productManager"的角色,所以他可以访问"查看产品","删除订单",但是访问"删除产品"时会提示
而user:“li4”拥有"productManager"的角色,所以他可以访问"删除产品",却不能访问"删除订单"。
这样一来就实现了权限的分配。
但是这个权限的分配过程,是通过在控制器对应方法上添加@RequirePermission和@RequiredRoles注解实现的。
真正项目开发的时候,这种方式就很有局限性了,当权限配置关系发生变化,每次都要修改代码,编译打包重启系统,这肯定是不能够被接受的。
所以,最好的方式,还是通过动态配置,哪个给不同的用户配置不同的角色,权限,修改之后立马生效这种方式。 为了实现这个效果,就需要基于URL配置的方式来做了。
接下来要做基于URL配置权限的讲解。 但是基于URL配置权限需要自己能够进行权限信息的灵活配置,那么就需要对权限信息一套进行维护。
1.对表结构进行调整
主要是增加了一些字段
1 DROP DATABASE IF EXISTS shiro; 2 CREATE DATABASE shiro DEFAULT CHARACTER SET utf8; 3 USE shiro; 4 5 drop table if exists user; 6 drop table if exists role; 7 drop table if exists permission; 8 drop table if exists user_role; 9 drop table if exists role_permission; 10 11 create table user ( 12 id bigint auto_increment, 13 name varchar(100), 14 password varchar(100), 15 salt varchar(100), 16 constraint pk_users primary key(id) 17 ) charset=utf8 ENGINE=InnoDB; 18 19 create table role ( 20 id bigint auto_increment, 21 name varchar(100), 22 desc_ varchar(100), 23 constraint pk_roles primary key(id) 24 ) charset=utf8 ENGINE=InnoDB; 25 26 create table permission ( 27 id bigint auto_increment, 28 name varchar(100), 29 desc_ varchar(100), 30 url varchar(100), 31 constraint pk_permissions primary key(id) 32 ) charset=utf8 ENGINE=InnoDB; 33 34 create table user_role ( 35 id bigint auto_increment, 36 uid bigint, 37 rid bigint, 38 constraint pk_users_roles primary key(id) 39 ) charset=utf8 ENGINE=InnoDB; 40 41 create table role_permission ( 42 id bigint auto_increment, 43 rid bigint, 44 pid bigint, 45 constraint pk_roles_permissions primary key(id) 46 ) charset=utf8 ENGINE=InnoDB;
1 INSERT INTO `permission` VALUES (1,'addProduct','增加产品','/addProduct'); 2 INSERT INTO `permission` VALUES (2,'deleteProduct','删除产品','/deleteProduct'); 3 INSERT INTO `permission` VALUES (3,'editeProduct','编辑产品','/editeProduct'); 4 INSERT INTO `permission` VALUES (4,'updateProduct','修改产品','/updateProduct'); 5 INSERT INTO `permission` VALUES (5,'listProduct','查看产品','/listProduct'); 6 INSERT INTO `permission` VALUES (6,'addOrder','增加订单','/addOrder'); 7 INSERT INTO `permission` VALUES (7,'deleteOrder','删除订单','/deleteOrder'); 8 INSERT INTO `permission` VALUES (8,'editeOrder','编辑订单','/editeOrder'); 9 INSERT INTO `permission` VALUES (9,'updateOrder','修改订单','/updateOrder'); 10 INSERT INTO `permission` VALUES (10,'listOrder','查看订单','/listOrder'); 11 INSERT INTO `role` VALUES (1,'admin','超级管理员'); 12 INSERT INTO `role` VALUES (2,'productManager','产品管理员'); 13 INSERT INTO `role` VALUES (3,'orderManager','订单管理员'); 14 INSERT INTO `role_permission` VALUES (1,1,1); 15 INSERT INTO `role_permission` VALUES (2,1,2); 16 INSERT INTO `role_permission` VALUES (3,1,3); 17 INSERT INTO `role_permission` VALUES (4,1,4); 18 INSERT INTO `role_permission` VALUES (5,1,5); 19 INSERT INTO `role_permission` VALUES (6,1,6); 20 INSERT INTO `role_permission` VALUES (7,1,7); 21 INSERT INTO `role_permission` VALUES (8,1,8); 22 INSERT INTO `role_permission` VALUES (9,1,9); 23 INSERT INTO `role_permission` VALUES (10,1,10); 24 INSERT INTO `role_permission` VALUES (11,2,1); 25 INSERT INTO `role_permission` VALUES (12,2,2); 26 INSERT INTO `role_permission` VALUES (13,2,3); 27 INSERT INTO `role_permission` VALUES (14,2,4); 28 INSERT INTO `role_permission` VALUES (15,2,5); 29 INSERT INTO `role_permission` VALUES (50,3,10); 30 INSERT INTO `role_permission` VALUES (51,3,9); 31 INSERT INTO `role_permission` VALUES (52,3,8); 32 INSERT INTO `role_permission` VALUES (53,3,7); 33 INSERT INTO `role_permission` VALUES (54,3,6); 34 INSERT INTO `role_permission` VALUES (55,3,1); 35 INSERT INTO `role_permission` VALUES (56,5,11); 36 INSERT INTO `user` VALUES (1,'zhang3','a7d59dfc5332749cb801f86a24f5f590','e5ykFiNwShfCXvBRPr3wXg=='); 37 INSERT INTO `user` VALUES (2,'li4','43e28304197b9216e45ab1ce8dac831b','jPz19y7arvYIGhuUjsb6sQ=='); 38 INSERT INTO `user_role` VALUES (43,2,2); 39 INSERT INTO `user_role` VALUES (45,1,1);
2.导入逆向工程需要的jar
1 <dependency> 2 <groupId>org.mybatis.generator</groupId> 3 <artifactId>mybatis-generator-core</artifactId> 4 <version>1.3.7</version> 5 </dependency>
3.generatorConfig.xml
用于指定需要生成哪些表的文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE generatorConfiguration 3 PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" 4 "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> 5 <generatorConfiguration> 6 7 <context id="DB2Tables" targetRuntime="MyBatis3"> 8 9 <!--是否在代码中去掉注释--> 10 <commentGenerator> 11 <property name="suppressDate" value="true" /> 12 <property name="suppressAllComments" value="true" /> 13 </commentGenerator> 14 15 <!--数据库链接地址账号密码--> 16 <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/shiro" userId="root" password="root"> 17 </jdbcConnection> 18 <!--不知道做什么用的。。。反正贴上来了~--> 19 <javaTypeResolver> 20 <property name="forceBigDecimals" value="false"/> 21 </javaTypeResolver> 22 <!--生成pojo类存放位置--> 23 <javaModelGenerator targetPackage="com.vi.entity" targetProject="src"> 24 <property name="enableSubPackages" value="true"/> 25 <property name="trimStrings" value="true"/> 26 </javaModelGenerator> 27 <!--生成xml映射文件存放位置--> 28 <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources/mapper"> 29 <property name="enableSubPackages" value="true"/> 30 </sqlMapGenerator> 31 <!--生成mapper类存放位置--> 32 <javaClientGenerator type="XMLMAPPER" targetPackage="com.vi.mapper" targetProject="src"> 33 <property name="enableSubPackages" value="true"/> 34 </javaClientGenerator> 35 36 <!--生成对应表及类名--> 37 <table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> 38 <property name="my.isgen.usekeys" value="true"/> 39 <property name="useActualColumnNames" value="true"/> 40 <generatedKey column="id" sqlStatement="JDBC"/> 41 </table> 42 <table tableName="role" domainObjectName="Role" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> 43 <property name="my.isgen.usekeys" value="true"/> 44 <property name="useActualColumnNames" value="true"/> 45 <generatedKey column="id" sqlStatement="JDBC"/> 46 </table> 47 <table tableName="permission" domainObjectName="Permission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> 48 <property name="my.isgen.usekeys" value="true"/> 49 <property name="useActualColumnNames" value="true"/> 50 <generatedKey column="id" sqlStatement="JDBC"/> 51 </table> 52 <table tableName="user_role" domainObjectName="UserRole" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> 53 <property name="my.isgen.usekeys" value="true"/> 54 <property name="useActualColumnNames" value="true"/> 55 <generatedKey column="id" sqlStatement="JDBC"/> 56 </table> 57 <table tableName="role_permission" domainObjectName="RolePermission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> 58 <property name="my.isgen.usekeys" value="true"/> 59 <property name="useActualColumnNames" value="true"/> 60 <generatedKey column="id" sqlStatement="JDBC"/> 61 </table> 62 63 </context> 64 </generatorConfiguration>
4.MybatisGenerator
运行这个程序以获取逆向工程生成的文件。
1 public class MybatisGenerator { 2 public static void main(String[] args) throws Exception { 3 4 List<String> warnings = new ArrayList<String>(); 5 boolean overwrite = true; 6 InputStream is= MybatisGenerator.class.getClassLoader().getResource("generatorConfig.xml").openStream(); 7 ConfigurationParser cp = new ConfigurationParser(warnings); 8 Configuration config = cp.parseConfiguration(is); 9 is.close(); 10 DefaultShellCallback callback = new DefaultShellCallback(overwrite); 11 MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); 12 myBatisGenerator.generate(null); 13 14 System.out.println("生成代码成功"); 15 16 } 17 }
5.Service层
UserService.java
1 public interface UserService { 2 /** 3 * 根据用户名获取密码 4 * @param name 5 * @return 6 */ 7 String getPassword(String name); 8 9 /** 10 * 根据用户名查找user 11 * @param name 12 * @return 13 */ 14 User getByName(String name); 15 16 List<User> list(); 17 18 void delete(Long id); 19 20 void add(User user); 21 22 User get(Long id); 23 24 void update(User user); 25 }
RoleService.java
1 public interface RoleService { 2 /** 3 * 根据用户名查找角色名 4 * @param username 5 * @return 6 */ 7 public Set<String> listRoleNames(String username); 8 9 /** 10 * 根据用户名查找角色 11 * @param username 12 * @return 13 */ 14 public Set<Role> listRoles(String username); 15 16 /** 17 * 根据用户查找角色 18 * @param user 19 * @return 20 */ 21 public Set<Role> listRoles(User user); 22 23 public List<Role> list(); 24 25 public void add(Role role); 26 27 public void delete(Long id); 28 29 public Role get(Long id); 30 31 public void update(Role role); 32 }
UserRoleService.java
1 public interface UserRoleService { 2 /** 3 * 给用户赋予对应的角色 4 * @param user 5 * @param roleIds 6 */ 7 void setRoles(User user, long[] roleIds); 8 9 void deleteByUser(long userId); 10 11 void deleteByRole(long roleId); 12 }
PermissionService.java
1 public interface PermissionService { 2 /** 3 * 根据用户名查找权限名 4 * @param username 5 * @return 6 */ 7 Set<String> listPermissions(String username); 8 9 /** 10 * 查询角色对应的权限 11 * @param role 12 * @return 13 */ 14 Set<Permission> listByRole(Role role); 15 16 List<Permission> list(); 17 18 void add(Permission permission); 19 20 void delete(Long id); 21 22 Permission get(Long id); 23 24 void update(Permission permission
RolePermissionService.java
1 public interface RolePermissionService { 2 /** 3 * 给角色赋予对应的权限 4 * @param role 5 * @param permissonIds 6 */ 7 void setPermissions(Role role, long[] permissonIds); 8 9 void deleteByRole(long roleId); 10 11 void deleteByPermission(long permissionId); 12 }
ServiceImpl
UserServiceImpl
1 @Service 2 public class UserServiceImpl implements UserService { 3 @Autowired 4 UserMapper userMapper; 5 @Autowired 6 UserRoleService userRoleService; 7 8 @Override 9 public String getPassword(String name) { 10 User user = getByName(name); 11 if (user == null) { 12 return null; 13 } 14 return user.getPassword(); 15 } 16 17 @Override 18 public User getByName(String name) { 19 UserExample example = new UserExample(); 20 example.createCriteria().andNameEqualTo(name); 21 List<User> users = userMapper.selectByExample(example); 22 if (users.isEmpty()) { 23 return null; 24 } 25 return users.get(0); 26 } 27 28 @Override 29 public List<User> list() { 30 UserExample example = new UserExample(); 31 example.setOrderByClause("id desc"); 32 return userMapper.selectByExample(example); 33 } 34 35 @Override 36 public void delete(Long id) { 37 userMapper.deleteByPrimaryKey(id); 38 userRoleService.deleteByUser(id); 39 } 40 41 @Override 42 public void add(User user) { 43 userMapper.insert(user); 44 } 45 46 @Override 47 public User get(Long id) { 48 return userMapper.selectByPrimaryKey(id); 49 } 50 51 @Override 52 public void update(User user) { 53 userMapper.updateByPrimaryKeySelective(user); 54 } 55 }
1 @Service 2 public class RoleServiceImpl implements RoleService { 3 @Autowired 4 RoleMapper roleMapper; 5 @Autowired 6 UserRoleMapper userRoleMapper; 7 @Autowired 8 UserService userService; 9 10 @Override 11 public Set<String> listRoleNames(String username) { 12 Set<String> result = new HashSet<>(); 13 List<Role> roles = listRoles(username); 14 for (Role role : roles) { 15 result.add(role.getName()); 16 } 17 return result; 18 } 19 20 @Override 21 public List<Role> listRoles(String username) { 22 List<Role> roles = new ArrayList<>(); 23 User user = userService.getByName(username); 24 if(user==null) 25 return roles; 26 roles = listRoles(user); 27 return roles; 28 } 29 30 @Override 31 public List<Role> listRoles(User user) { 32 List<Role> roles = new ArrayList<>(); 33 UserRoleExample userRoleExample = new UserRoleExample(); 34 userRoleExample.createCriteria().andUidEqualTo(user.getId()); 35 List<UserRole> userRoles = userRoleMapper.selectByExample(userRoleExample); 36 for (UserRole userRole : userRoles) { 37 roles.add(roleMapper.selectByPrimaryKey(userRole.getRid())); 38 39 } 40 return roles; 41 } 42 43 @Override 44 public List<Role> list() { 45 RoleExample example = new RoleExample(); 46 example.setOrderByClause("id desc"); 47 return roleMapper.selectByExample(example); 48 } 49 50 @Override 51 public void add(Role role) { 52 roleMapper.insert(role); 53 } 54 55 @Override 56 public void delete(Long id) { 57 roleMapper.deleteByPrimaryKey(id); 58 } 59 60 @Override 61 public Role get(Long id) { 62 return roleMapper.selectByPrimaryKey(id); 63 } 64 65 @Override 66 public void update(Role role) { 67 roleMapper.updateByPrimaryKeySelective(role); 68 } 69 }