首页 > 代码库 > 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao
2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao
原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398
根据下载的pdf学习。
第二十一章 授予身份与切换身份(一)
1.使用场景
某个领导因为某些原因不能访问一些网站,他想把这个网站上的工作委托给秘书,但是他又不想提供账户、密码。此时可以使用shiro的 RunAs 功能。
RunAs:允许一个用户假装为另一个用户(如果获得了允许)的身份进行访问。
注意,本章代码基于《第十六章 综合实例》,详细的数据模型及基本流程见该章。
2.表及数据
请运行 shiro-example-chapter21/sql/ shiro-schema.sql 表结构
请运行 shiro-example-chapter21/sql/ shiro-data.sql 数据
1 drop table if exists sys_user; 2 drop table if exists sys_organization; 3 drop table if exists sys_resource; 4 drop table if exists sys_role; 5 drop table if exists sys_user_runas; 6 7 create table sys_user ( 8 id bigint auto_increment, 9 organization_id bigint, 10 username varchar(100), 11 password varchar(100), 12 salt varchar(100), 13 role_ids varchar(100), 14 locked bool default false, 15 constraint pk_sys_user primary key(id) 16 ) charset=utf8 ENGINE=InnoDB; 17 create unique index idx_sys_user_username on sys_user(username); 18 create index idx_sys_user_organization_id on sys_user(organization_id); 19 20 create table sys_organization ( 21 id bigint auto_increment, 22 name varchar(100), 23 parent_id bigint, 24 parent_ids varchar(100), 25 available bool default false, 26 constraint pk_sys_organization primary key(id) 27 ) charset=utf8 ENGINE=InnoDB; 28 create index idx_sys_organization_parent_id on sys_organization(parent_id); 29 create index idx_sys_organization_parent_ids on sys_organization(parent_ids); 30 31 32 create table sys_resource ( 33 id bigint auto_increment, 34 name varchar(100), 35 type varchar(50), 36 url varchar(200), 37 parent_id bigint, 38 parent_ids varchar(100), 39 permission varchar(100), 40 available bool default false, 41 constraint pk_sys_resource primary key(id) 42 ) charset=utf8 ENGINE=InnoDB; 43 create index idx_sys_resource_parent_id on sys_resource(parent_id); 44 create index idx_sys_resource_parent_ids on sys_resource(parent_ids); 45 46 create table sys_role ( 47 id bigint auto_increment, 48 role varchar(100), 49 description varchar(100), 50 resource_ids varchar(100), 51 available bool default false, 52 constraint pk_sys_role primary key(id) 53 ) charset=utf8 ENGINE=InnoDB; 54 create index idx_sys_role_resource_ids on sys_role(resource_ids); 55 56 create table sys_user_runas ( 57 from_user_id bigint, 58 to_user_id bigint, 59 constraint pk_sys_user_runas primary key(from_user_id, to_user_id) 60 ) charset=utf8 ENGINE=InnoDB;
1 DELIMITER ; 2 delete from sys_user; 3 delete from sys_role; 4 delete from sys_resource; 5 delete from sys_organization; 6 delete from sys_user_runas; 7 8 insert into sys_user values(1,1,‘admin‘,‘d3c59d25033dbf980d29554025c23a75‘,‘8d78869f470951332959580424d4bf4f‘, ‘1‘, false); 9 insert into sys_user values(2,1,‘zhang‘,‘c6a02f6c9a5aaf311ec94009b6b024d0‘,‘588ae709311808bd7e5fade1c84407c7‘, ‘1‘, false); 10 insert into sys_user values(3,1,‘wang‘,‘2e6f83bdaef108d4f23b2a1f2b9928cc‘,‘bd647b15f6724ea711272c4a3c6d16c0‘, ‘1‘, false); 11 12 insert into sys_organization values(1, ‘总公司‘, 0, ‘0/‘, true); 13 insert into sys_organization values(2, ‘分公司1‘, 1, ‘0/1/‘, true); 14 insert into sys_organization values(3, ‘分公司2‘, 1, ‘0/1/‘, true); 15 insert into sys_organization values(4, ‘分公司11‘, 2, ‘0/1/2/‘, true); 16 17 insert into sys_resource values(1, ‘资源‘, ‘menu‘, ‘‘, 0, ‘0/‘, ‘‘, true); 18 19 insert into sys_resource values(11, ‘组织机构管理‘, ‘menu‘, ‘/organization‘, 1, ‘0/1/‘, ‘organization:*‘, true); 20 insert into sys_resource values(12, ‘组织机构新增‘, ‘button‘, ‘‘, 11, ‘0/1/11/‘, ‘organization:create‘, true); 21 insert into sys_resource values(13, ‘组织机构修改‘, ‘button‘, ‘‘, 11, ‘0/1/11/‘, ‘organization:update‘, true); 22 insert into sys_resource values(14, ‘组织机构删除‘, ‘button‘, ‘‘, 11, ‘0/1/11/‘, ‘organization:delete‘, true); 23 insert into sys_resource values(15, ‘组织机构查看‘, ‘button‘, ‘‘, 11, ‘0/1/11/‘, ‘organization:view‘, true); 24 25 insert into sys_resource values(21, ‘用户管理‘, ‘menu‘, ‘/user‘, 1, ‘0/1/‘, ‘user:*‘, true); 26 insert into sys_resource values(22, ‘用户新增‘, ‘button‘, ‘‘, 21, ‘0/1/21/‘, ‘user:create‘, true); 27 insert into sys_resource values(23, ‘用户修改‘, ‘button‘, ‘‘, 21, ‘0/1/21/‘, ‘user:update‘, true); 28 insert into sys_resource values(24, ‘用户删除‘, ‘button‘, ‘‘, 21, ‘0/1/21/‘, ‘user:delete‘, true); 29 insert into sys_resource values(25, ‘用户查看‘, ‘button‘, ‘‘, 21, ‘0/1/21/‘, ‘user:view‘, true); 30 31 insert into sys_resource values(31, ‘资源管理‘, ‘menu‘, ‘/resource‘, 1, ‘0/1/‘, ‘resource:*‘, true); 32 insert into sys_resource values(32, ‘资源新增‘, ‘button‘, ‘‘, 31, ‘0/1/31/‘, ‘resource:create‘, true); 33 insert into sys_resource values(33, ‘资源修改‘, ‘button‘, ‘‘, 31, ‘0/1/31/‘, ‘resource:update‘, true); 34 insert into sys_resource values(34, ‘资源删除‘, ‘button‘, ‘‘, 31, ‘0/1/31/‘, ‘resource:delete‘, true); 35 insert into sys_resource values(35, ‘资源查看‘, ‘button‘, ‘‘, 31, ‘0/1/31/‘, ‘resource:view‘, true); 36 37 insert into sys_resource values(41, ‘角色管理‘, ‘menu‘, ‘/role‘, 1, ‘0/1/‘, ‘role:*‘, true); 38 insert into sys_resource values(42, ‘角色新增‘, ‘button‘, ‘‘, 41, ‘0/1/41/‘, ‘role:create‘, true); 39 insert into sys_resource values(43, ‘角色修改‘, ‘button‘, ‘‘, 41, ‘0/1/41/‘, ‘role:update‘, true); 40 insert into sys_resource values(44, ‘角色删除‘, ‘button‘, ‘‘, 41, ‘0/1/41/‘, ‘role:delete‘, true); 41 insert into sys_resource values(45, ‘角色查看‘, ‘button‘, ‘‘, 41, ‘0/1/41/‘, ‘role:view‘, true); 42 43 insert into sys_role values(1, ‘admin‘, ‘超级管理员‘, ‘11,21,31,41‘, true);
增加的sql语句:
1 drop table if exists sys_user_runas; 2 create table sys_user_runas ( 3 from_user_id bigint, 4 to_user_id bigint, 5 constraint pk_sys_user_runas primary key(from_user_id, to_user_id) 6 ) charset=utf8 ENGINE=InnoDB;
3.实体entity
1 package com.github.zhangkaitao.shiro.chapter21.entity; 2 import java.io.Serializable; 3 4 public class Organization implements Serializable { 5 private Long id; //编号 6 private String name; //组织机构名称 7 private Long parentId; //父编号 8 private String parentIds; //父编号列表,如1/2/ 9 private Boolean available = Boolean.FALSE; 10 11 //getter、setter略 12 13 public boolean isRootNode() { 14 return parentId == 0; 15 } 16 17 public String makeSelfAsParentIds() { 18 return getParentIds() + getId() + "/"; 19 } 20 21 @Override 22 public boolean equals(Object o) { 23 if (this == o) return true; 24 if (o == null || getClass() != o.getClass()) return false; 25 26 Organization that = (Organization) o; 27 28 if (id != null ? !id.equals(that.id) : that.id != null) return false; 29 30 return true; 31 } 32 33 @Override 34 public int hashCode() { 35 return id != null ? id.hashCode() : 0; 36 } 37 38 @Override 39 public String toString() { 40 return "Organization{" + 41 "id=" + id + 42 ", name=‘" + name + ‘\‘‘ + 43 ", parentId=" + parentId + 44 ", parentIds=‘" + parentIds + ‘\‘‘ + 45 ", available=" + available + 46 ‘}‘; 47 } 48 }
1 package com.github.zhangkaitao.shiro.chapter21.entity; 2 import java.io.Serializable; 3 4 public class Resource implements Serializable { 5 private Long id; //编号 6 private String name; //资源名称 7 private ResourceType type = ResourceType.menu; //资源类型 8 private String url; //资源路径 9 private String permission; //权限字符串 10 private Long parentId; //父编号 11 private String parentIds; //父编号列表 12 private Boolean available = Boolean.FALSE; 13 14 public static enum ResourceType { 15 menu("菜单"), button("按钮"); 16 17 private final String info; 18 private ResourceType(String info) { 19 this.info = info; 20 } 21 22 public String getInfo() { 23 return info; 24 } 25 } 26 27 //getter、setter略 28 29 public boolean isRootNode() { 30 return parentId == 0; 31 } 32 33 public String makeSelfAsParentIds() { 34 return getParentIds() + getId() + "/"; 35 } 36 37 @Override 38 public boolean equals(Object o) { 39 if (this == o) return true; 40 if (o == null || getClass() != o.getClass()) return false; 41 42 Resource resource = (Resource) o; 43 44 if (id != null ? !id.equals(resource.id) : resource.id != null) return false; 45 46 return true; 47 } 48 49 @Override 50 public int hashCode() { 51 return id != null ? id.hashCode() : 0; 52 } 53 54 @Override 55 public String toString() { 56 return "Resource{" + 57 "id=" + id + 58 ", name=‘" + name + ‘\‘‘ + 59 ", type=" + type + 60 ", permission=‘" + permission + ‘\‘‘ + 61 ", parentId=" + parentId + 62 ", parentIds=‘" + parentIds + ‘\‘‘ + 63 ", available=" + available + 64 ‘}‘; 65 } 66 }
1 package com.github.zhangkaitao.shiro.chapter21.entity; 2 3 import org.springframework.util.CollectionUtils; 4 import org.springframework.util.StringUtils; 5 import java.io.Serializable; 6 import java.util.ArrayList; 7 import java.util.List; 8 9 public class Role implements Serializable { 10 private Long id; //编号 11 private String role; //角色标识 程序中判断使用,如"admin" 12 private String description; //角色描述,UI界面显示使用 13 private List<Long> resourceIds; //拥有的资源 14 private Boolean available = Boolean.FALSE; //是否可用,如果不可用将不会添加给用户 15 16 public Role() { 17 } 18 19 public Role(String role, String description, Boolean available) { 20 this.role = role; 21 this.description = description; 22 this.available = available; 23 } 24 25 //getter、setter略 26 public List<Long> getResourceIds() { 27 if(resourceIds == null) { 28 resourceIds = new ArrayList<Long>(); 29 } 30 return resourceIds; 31 } 32 33 public void setResourceIds(List<Long> resourceIds) { 34 this.resourceIds = resourceIds; 35 } 36 37 public String getResourceIdsStr() { 38 if(CollectionUtils.isEmpty(resourceIds)) { 39 return ""; 40 } 41 StringBuilder s = new StringBuilder(); 42 for(Long resourceId : resourceIds) { 43 s.append(resourceId); 44 s.append(","); 45 } 46 return s.toString(); 47 } 48 49 public void setResourceIdsStr(String resourceIdsStr) { 50 if(StringUtils.isEmpty(resourceIdsStr)) { 51 return; 52 } 53 String[] resourceIdStrs = resourceIdsStr.split(","); 54 for(String resourceIdStr : resourceIdStrs) { 55 if(StringUtils.isEmpty(resourceIdStr)) { 56 continue; 57 } 58 getResourceIds().add(Long.valueOf(resourceIdStr)); 59 } 60 } 61 62 63 @Override 64 public boolean equals(Object o) { 65 if (this == o) return true; 66 if (o == null || getClass() != o.getClass()) return false; 67 68 Role role = (Role) o; 69 70 if (id != null ? !id.equals(role.id) : role.id != null) return false; 71 72 return true; 73 } 74 75 @Override 76 public int hashCode() { 77 return id != null ? id.hashCode() : 0; 78 } 79 80 @Override 81 public String toString() { 82 return "Role{" + 83 "id=" + id + 84 ", role=‘" + role + ‘\‘‘ + 85 ", description=‘" + description + ‘\‘‘ + 86 ", resourceIds=" + resourceIds + 87 ", available=" + available + 88 ‘}‘; 89 } 90 }
1 package com.github.zhangkaitao.shiro.chapter21.entity; 2 3 import org.springframework.util.CollectionUtils; 4 import org.springframework.util.StringUtils; 5 import java.io.Serializable; 6 import java.util.ArrayList; 7 import java.util.List; 8 9 public class User implements Serializable { 10 private Long id; //编号 11 private Long organizationId; //所属公司 12 private String username; //用户名 13 private String password; //密码 14 private String salt; //加密密码的盐 15 private List<Long> roleIds; //拥有的角色列表 16 private Boolean locked = Boolean.FALSE; 17 18 public User() { 19 } 20 21 public User(String username, String password) { 22 this.username = username; 23 this.password = password; 24 } 25 26 //getter、setter略 27 28 public String getCredentialsSalt() { 29 return username + salt; 30 } 31 32 public List<Long> getRoleIds() { 33 if(roleIds == null) { 34 roleIds = new ArrayList<Long>(); 35 } 36 return roleIds; 37 } 38 39 public void setRoleIds(List<Long> roleIds) { 40 this.roleIds = roleIds; 41 } 42 43 public String getRoleIdsStr() { 44 if(CollectionUtils.isEmpty(roleIds)) { 45 return ""; 46 } 47 StringBuilder s = new StringBuilder(); 48 for(Long roleId : roleIds) { 49 s.append(roleId); 50 s.append(","); 51 } 52 return s.toString(); 53 } 54 55 public void setRoleIdsStr(String roleIdsStr) { 56 if(StringUtils.isEmpty(roleIdsStr)) { 57 return; 58 } 59 String[] roleIdStrs = roleIdsStr.split(","); 60 for(String roleIdStr : roleIdStrs) { 61 if(StringUtils.isEmpty(roleIdStr)) { 62 continue; 63 } 64 getRoleIds().add(Long.valueOf(roleIdStr)); 65 } 66 } 67 68 @Override 69 public boolean equals(Object o) { 70 if (this == o) return true; 71 if (o == null || getClass() != o.getClass()) return false; 72 73 User user = (User) o; 74 75 if (id != null ? !id.equals(user.id) : user.id != null) return false; 76 77 return true; 78 } 79 80 @Override 81 public int hashCode() { 82 return id != null ? id.hashCode() : 0; 83 } 84 85 @Override 86 public String toString() { 87 return "User{" + 88 "id=" + id + 89 ", organizationId=" + organizationId + 90 ", username=‘" + username + ‘\‘‘ + 91 ", password=‘" + password + ‘\‘‘ + 92 ", salt=‘" + salt + ‘\‘‘ + 93 ", roleIds=" + roleIds + 94 ", locked=" + locked + 95 ‘}‘; 96 } 97 }
这都是前面章节的内容了。重点是UserRunAs。该实体定义了授予身份账号(A)与被授予身份账号(B)的关系。B将假装为A进行访问。
1 package com.github.zhangkaitao.shiro.chapter21.entity; 2 3 import java.io.Serializable; 4 5 public class UserRunAs implements Serializable { 6 private Long fromUserId;//授予身份帐号 7 private Long toUserId;//被授予身份帐号 8 9 //getter、setter略 10 11 @Override 12 public boolean equals(Object o) { 13 if (this == o) return true; 14 if (o == null || getClass() != o.getClass()) return false; 15 16 UserRunAs userRunAs = (UserRunAs) o; 17 18 if (fromUserId != null ? !fromUserId.equals(userRunAs.fromUserId) : userRunAs.fromUserId != null) return false; 19 if (toUserId != null ? !toUserId.equals(userRunAs.toUserId) : userRunAs.toUserId != null) return false; 20 21 return true; 22 } 23 24 @Override 25 public int hashCode() { 26 int result = fromUserId != null ? fromUserId.hashCode() : 0; 27 result = 31 * result + (toUserId != null ? toUserId.hashCode() : 0); 28 return result; 29 } 30 31 @Override 32 public String toString() { 33 return "UserRunAs{" + 34 "fromUserId=" + fromUserId + 35 ", toUserId=" + toUserId + 36 ‘}‘; 37 } 38 }
4.Service层
其他的就只放接口类了,runas相关的会放上实现类。
1 package com.github.zhangkaitao.shiro.chapter21.service; 2 3 import com.github.zhangkaitao.shiro.chapter21.entity.Organization; 4 import java.util.List; 5 6 public interface OrganizationService { 7 8 public Organization createOrganization(Organization organization); 9 public Organization updateOrganization(Organization organization); 10 public void deleteOrganization(Long organizationId); 11 12 Organization findOne(Long organizationId); 13 List<Organization> findAll(); 14 15 Object findAllWithExclude(Organization excludeOraganization); 16 17 void move(Organization source, Organization target); 18 }
1 package com.github.zhangkaitao.shiro.chapter21.service; 2 3 import com.github.zhangkaitao.shiro.chapter21.entity.Resource; 4 import java.util.List; 5 import java.util.Set; 6 7 public interface ResourceService { 8 9 public Resource createResource(Resource resource); 10 public Resource updateResource(Resource resource); 11 public void deleteResource(Long resourceId); 12 13 Resource findOne(Long resourceId); 14 List<Resource> findAll(); 15 16 /** 17 * 得到资源对应的权限字符串 18 * @param resourceIds 19 * @return 20 */ 21 Set<String> findPermissions(Set<Long> resourceIds); 22 23 /** 24 * 根据用户权限得到菜单 25 * @param permissions 26 * @return 27 */ 28 List<Resource> findMenus(Set<String> permissions); 29 }
1 package com.github.zhangkaitao.shiro.chapter21.service; 2 3 import com.github.zhangkaitao.shiro.chapter21.entity.Role; 4 import java.util.List; 5 import java.util.Set; 6 7 public interface RoleService { 8 9 public Role createRole(Role role); 10 public Role updateRole(Role role); 11 public void deleteRole(Long roleId); 12 13 public Role findOne(Long roleId); 14 public List<Role> findAll(); 15 16 /** 17 * 根据角色编号得到角色标识符列表 18 * @param roleIds 19 * @return 20 */ 21 Set<String> findRoles(Long... roleIds); 22 23 /** 24 * 根据角色编号得到权限字符串列表 25 * @param roleIds 26 * @return 27 */ 28 Set<String> findPermissions(Long[] roleIds); 29 }
1 package com.github.zhangkaitao.shiro.chapter21.service; 2 3 import com.github.zhangkaitao.shiro.chapter21.entity.User; 4 import java.util.List; 5 import java.util.Set; 6 7 public interface UserService { 8 9 public User createUser(User user); 10 public User updateUser(User user); 11 public void deleteUser(Long userId); 12 13 14 public void changePassword(Long userId, String newPassword); 15 16 User findOne(Long userId); 17 List<User> findAll(); 18 public User findByUsername(String username); 19 20 /** 21 * 根据用户名查找其角色 22 * @param username 23 * @return 24 */ 25 public Set<String> findRoles(String username); 26 27 /** 28 * 根据用户名查找其权限 29 * @param username 30 * @return 31 */ 32 public Set<String> findPermissions(String username); 33 34 }
RunAsService:
1 package com.github.zhangkaitao.shiro.chapter21.service; 2 import java.util.List; 3 4 public interface UserRunAsService { 5 6 public void grantRunAs(Long fromUserId, Long toUserId);//授予身份 7 public void revokeRunAs(Long fromUserId, Long toUserId);//回收身份 8 9 public boolean exists(Long fromUserId, Long toUserId);//关系存在 10 11 public List<Long> findFromUserIds(Long toUserId);//查找 12 public List<Long> findToUserIds(Long fromUserId);//查找 13 14 }
UserRunAsServiceImpl:
1 package com.github.zhangkaitao.shiro.chapter21.service; 2 3 import com.github.zhangkaitao.shiro.chapter21.dao.UserRunAsDao; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.stereotype.Service; 6 import java.util.List; 7 8 @Service 9 public class UserRunAsServiceImpl implements UserRunAsService { 10 @Autowired 11 private UserRunAsDao userRunAsDao; 12 13 @Override 14 public void grantRunAs(Long fromUserId, Long toUserId) { 15 userRunAsDao.grantRunAs(fromUserId, toUserId); 16 } 17 18 @Override 19 public void revokeRunAs(Long fromUserId, Long toUserId) { 20 userRunAsDao.revokeRunAs(fromUserId, toUserId); 21 } 22 23 @Override 24 public boolean exists(Long fromUserId, Long toUserId) { 25 return userRunAsDao.exists(fromUserId, toUserId); 26 } 27 28 @Override 29 public List<Long> findFromUserIds(Long toUserId) { 30 return userRunAsDao.findFromUserIds(toUserId); 31 } 32 33 @Override 34 public List<Long> findToUserIds(Long fromUserId) { 35 return userRunAsDao.findToUserIds(fromUserId); 36 } 37 }
5.Dao层
同样,其他的几个就只放接口了。
1 package com.github.zhangkaitao.shiro.chapter21.dao; 2 3 import com.github.zhangkaitao.shiro.chapter21.entity.Organization; 4 import java.util.List; 5 6 public interface OrganizationDao { 7 8 public Organization createOrganization(Organization organization); 9 public Organization updateOrganization(Organization organization); 10 public void deleteOrganization(Long organizationId); 11 12 Organization findOne(Long organizationId); 13 List<Organization> findAll(); 14 15 List<Organization> findAllWithExclude(Organization excludeOraganization); 16 17 void move(Organization source, Organization target); 18 }
1 package com.github.zhangkaitao.shiro.chapter21.dao; 2 3 import com.github.zhangkaitao.shiro.chapter21.entity.Resource; 4 import java.util.List; 5 6 public interface ResourceDao { 7 8 public Resource createResource(Resource resource); 9 public Resource updateResource(Resource resource); 10 public void deleteResource(Long resourceId); 11 12 Resource findOne(Long resourceId); 13 List<Resource> findAll(); 14 15 }
1 package com.github.zhangkaitao.shiro.chapter21.dao; 2 3 import com.github.zhangkaitao.shiro.chapter21.entity.Role; 4 import java.util.List; 5 6 public interface RoleDao { 7 8 public Role createRole(Role role); 9 public Role updateRole(Role role); 10 public void deleteRole(Long roleId); 11 12 public Role findOne(Long roleId); 13 public List<Role> findAll(); 14 }
1 package com.github.zhangkaitao.shiro.chapter21.dao; 2 3 import com.github.zhangkaitao.shiro.chapter21.entity.User; 4 import java.util.List; 5 6 public interface UserDao { 7 8 public User createUser(User user); 9 public User updateUser(User user); 10 public void deleteUser(Long userId); 11 12 User findOne(Long userId); 13 List<User> findAll(); 14 User findByUsername(String username); 15 16 }
UserRunAsDao:
1 package com.github.zhangkaitao.shiro.chapter21.dao; 2 3 import java.util.List; 4 5 public interface UserRunAsDao { 6 7 public void grantRunAs(Long fromUserId, Long toUserId); 8 public void revokeRunAs(Long fromUserId, Long toUserId); 9 10 public boolean exists(Long fromUserId, Long toUserId); 11 12 public List<Long> findFromUserIds(Long toUserId); 13 public List<Long> findToUserIds(Long fromUserId); 14 15 }
UserRunAsDaoImpl:
1 package com.github.zhangkaitao.shiro.chapter21.dao; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.jdbc.core.JdbcTemplate; 5 import org.springframework.stereotype.Repository; 6 import java.util.List; 7 8 @Repository 9 public class UserRunAsDaoImpl implements UserRunAsDao { 10 11 @Autowired 12 private JdbcTemplate jdbcTemplate; 13 14 @Override 15 public void grantRunAs(Long fromUserId, Long toUserId) { 16 String sql = "insert into sys_user_runas(from_user_id, to_user_id) values (?,?)"; 17 if(!exists(fromUserId, toUserId)) { 18 jdbcTemplate.update(sql, fromUserId, toUserId); 19 } 20 } 21 22 public boolean exists(Long fromUserId, Long toUserId) { 23 String sql = "select count(1) from sys_user_runas where from_user_id=? and to_user_id=?"; 24 return jdbcTemplate.queryForObject(sql, Integer.class, fromUserId, toUserId) != 0; 25 } 26 27 @Override 28 public void revokeRunAs(Long fromUserId, Long toUserId) { 29 String sql = "delete from sys_user_runas where from_user_id=? and to_user_id=?"; 30 jdbcTemplate.update(sql, fromUserId, toUserId); 31 } 32 33 @Override 34 public List<Long> findFromUserIds(Long toUserId) { 35 String sql = "select from_user_id from sys_user_runas where to_user_id=?"; 36 return jdbcTemplate.queryForList(sql, Long.class, toUserId); 37 } 38 39 @Override 40 public List<Long> findToUserIds(Long fromUserId) { 41 String sql = "select to_user_id from sys_user_runas where from_user_id=?"; 42 return jdbcTemplate.queryForList(sql, Long.class, fromUserId); 43 } 44 }
6.Realm
1 package com.github.zhangkaitao.shiro.chapter21.realm; 2 3 import com.github.zhangkaitao.shiro.chapter21.entity.User; 4 import com.github.zhangkaitao.shiro.chapter21.service.UserService; 5 import org.apache.shiro.authc.*; 6 import org.apache.shiro.authz.AuthorizationInfo; 7 import org.apache.shiro.authz.SimpleAuthorizationInfo; 8 import org.apache.shiro.realm.AuthorizingRealm; 9 import org.apache.shiro.subject.PrincipalCollection; 10 import org.apache.shiro.util.ByteSource; 11 import org.springframework.beans.factory.annotation.Autowired; 12 13 public class UserRealm extends AuthorizingRealm { 14 15 @Autowired 16 private UserService userService; 17 18 @Override 19 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 20 String username = (String)principals.getPrimaryPrincipal(); 21 22 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); 23 authorizationInfo.setRoles(userService.findRoles(username)); 24 authorizationInfo.setStringPermissions(userService.findPermissions(username)); 25 return authorizationInfo; 26 } 27 28 @Override 29 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 30 31 String username = (String)token.getPrincipal(); 32 33 User user = userService.findByUsername(username); 34 35 if(user == null) { 36 throw new UnknownAccountException();//没找到帐号 37 } 38 39 if(Boolean.TRUE.equals(user.getLocked())) { 40 throw new LockedAccountException(); //帐号锁定 41 } 42 43 //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现 44 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( 45 user.getUsername(), //用户名 46 user.getPassword(), //密码 47 ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt 48 getName() //realm name 49 ); 50 return authenticationInfo; 51 } 52 53 @Override 54 public void clearCachedAuthorizationInfo(PrincipalCollection principals) { 55 super.clearCachedAuthorizationInfo(principals); 56 } 57 58 @Override 59 public void clearCachedAuthenticationInfo(PrincipalCollection principals) { 60 super.clearCachedAuthenticationInfo(principals); 61 } 62 63 @Override 64 public void clearCache(PrincipalCollection principals) { 65 super.clearCache(principals); 66 } 67 68 public void clearAllCachedAuthorizationInfo() { 69 getAuthorizationCache().clear(); 70 } 71 72 public void clearAllCachedAuthenticationInfo() { 73 getAuthenticationCache().clear(); 74 } 75 76 public void clearAllCache() { 77 clearAllCachedAuthenticationInfo(); 78 clearAllCachedAuthorizationInfo(); 79 } 80 81 }
1 package com.github.zhangkaitao.shiro.chapter21.credentials; 2 3 import org.apache.shiro.authc.AuthenticationInfo; 4 import org.apache.shiro.authc.AuthenticationToken; 5 import org.apache.shiro.authc.ExcessiveAttemptsException; 6 import org.apache.shiro.authc.credential.HashedCredentialsMatcher; 7 import org.apache.shiro.cache.Cache; 8 import org.apache.shiro.cache.CacheManager; 9 import java.util.concurrent.atomic.AtomicInteger; 10 11 public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher { 12 13 private Cache<String, AtomicInteger> passwordRetryCache; 14 15 public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) { 16 passwordRetryCache = cacheManager.getCache("passwordRetryCache"); 17 } 18 19 @Override 20 public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { 21 String username = (String)token.getPrincipal(); 22 //retry count + 1 23 AtomicInteger retryCount = passwordRetryCache.get(username); 24 if(retryCount == null) { 25 retryCount = new AtomicInteger(0); 26 passwordRetryCache.put(username, retryCount); 27 } 28 if(retryCount.incrementAndGet() > 5) { 29 //if retry count > 5 throw 30 throw new ExcessiveAttemptsException(); 31 } 32 33 boolean matches = super.doCredentialsMatch(token, info); 34 if(matches) { 35 //clear retry count 36 passwordRetryCache.remove(username); 37 } 38 return matches; 39 } 40 }
7.配置文件
略。
8.其他类
略。
由上可知,添加的东西有:
1 table:sys_user_runas 2 entity:UserRunAs 3 service:UserRunAsService、UserRunAsServiceImpl 4 dao:UserRunAsDao、UserRunAsDaoImpl
有daoImpl中的代码可知,它只是处理表sys_user_runas的一些基本增删改查操作。那么究竟是如何实现B可以嫁接A的身份进行呢?
请看:2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(二) controller
2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao