首页 > 代码库 > 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;
shiro-schema.sql
技术分享
 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);
shiro-data.sql

 

增加的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 }
Organization
技术分享
 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 }
Resource
技术分享
 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 }
Role
技术分享
 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 }
User

 

这都是前面章节的内容了。重点是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 }
OrganizationService
技术分享
 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 }
ResourceService
技术分享
 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 }
RoleService
技术分享
 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 }
UserService

 

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 }
OrganizationDao
技术分享
 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 }
ResourceDao
技术分享
 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 }
RoleDao
技术分享
 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 }
UserDao

 

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 }
UserRealm
技术分享
 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 }
RetryLimitHashedCredentialsMatcher

 

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