Web中常用的权限管理模型是RBAC(基于角色的访问控制)。
RBAC的核心就是:"Who对What进行How的操作"。
Who :权限的主体,比如 User。
What:权限针对的资源,比如 用户管理。
How :具体的权限,比如 增加用户、删除用户。
1、先看看RBAC模型的实体关系图。
2、各个实体的说明。
1)组织(Oraganization):一个公司的组织架构、部门。这是一个树形的结构。比如赛思科技有限公司是一个顶级组织,它下面有软件研发部、市场部、销售部等子组织,那软件研发部的父组织就是赛思科技有限公司。组织---》用户 是一对多的关系。
2)用户(User):用户里面的组织字段就是指用户所属的组织,比如张三输属于软件研发部。用户---》组织 是多对一的关系。用户---》角色 是多对多关系,由一张关联表来保存这种多对多关系。
3)角色(Role):特定权限的集合。角色---》资源 是多对多的关系,由一张关联表保存这种多对多关系。角色---》操作 是一对多的关系。角色、资源和操作三者之间的关系是:特定角色对特定资源有哪些操作。比如"超级管理员"这个角色,拥有对"用户管理"这个资源的"增加用户"这个操作。
4)资源(Rsource):系统的资源,模块之类的。资源是树形结构。比如说"系统管理"这个资源有两个下级资源:"用户管理"和"日志管理"。资源---》角色 是多对多的关系,由一张关联表保存这种多对多关系。资源---》操作 是一对多的关系,比如"用户管理"这个资源可以有"增加用户"、"删除用户"、"编辑用户"操作。
5)操作(Operator):针对某个资源的增删改查操作。
3、角色、资源、操作的特别说明。
有两种角色:超级管理员、普通用户。
有一个资源:用户管理。
这个资源能执行的操作:增加用户、删除用户、编辑用户、查找用户。
超级管理员角色对用户管理可以进行增加用户、删除用户、编辑用户和查找用户操作。
普通用户角色对用户管理只可以进行查找用户操作。
对某个用户进行权限控制的时候,根据用户的角色获得用户可以访问的资源,再根据用户的角色和可以访问的特定的资源获得用户对该资源的操作。
4、JPA映射的实体。
1)组织(Organization):
/** * 组织架构 * @author Luxh */ @Entity @Table(name="t_organization") public class Organization { @Id @GeneratedValue private Long id; /**组织名称*/ @Column(length=64) private String name; /**组织编码*/ @Column(length=64) private String code; /**父组织*/ @ManyToOne @JoinColumn(name="parent_id") private Organization parent; /**子组织*/ @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY) @JoinColumn(name="parent_id") private Set<Organization> children = new HashSet<Organization>(); /** * 拥有的用户 */ @OneToMany(mappedBy="organization",cascade=CascadeType.ALL,fetch=FetchType.LAZY) private Set<User> users = new HashSet<User>(); //省略get/set方法 //... }
2)用户(User):
/** * 用户 * @author Luxh */ @Entity @Table(name="t_user") public class User { @Id @GeneratedValue private Long id; /**账号*/ @Column(length=32) private String account; /**密码*/ @Column(length=32) private String password; /**姓名*/ @Column(length=32) private String name; /**性别*/ @Column(length=4) private String gender; /**邮箱*/ @Column(length=32) private String email; /**手机号码*/ @Column(length=20) private String mobileNumber; /** * 所属组织 */ @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH}) @JoinColumn(name="organization_id") private Organization organization; /** * 拥有的角色 */ @ManyToMany @JoinTable(name="t_user_role",joinColumns=@JoinColumn(name="user_id"), inverseJoinColumns=@JoinColumn(name="role_id")) private Set<Role> roles = new HashSet<Role>(); //省略get/set方法 //... }
3)角色(Role):
/** * 角色 * @author Luxh */ @Entity @Table(name="t_role") public class Role { @Id @GeneratedValue private Long id; /**角色名称*/ @Column(length=64) private String name; /**角色代码*/ @Column(length=64) private String code; /**角色描述*/ @Column(length=256) private String description; /** * 被分配给的用户 */ @ManyToMany(mappedBy="roles") private Set<User> users = new HashSet<User>(); /** * 可以访问的资源 */ @ManyToMany(mappedBy="roles") private Set<Resource> resources = new HashSet<Resource>(); /** * 可以对访问的资源进行的操作 */ @OneToMany(mappedBy="role",cascade=CascadeType.ALL,fetch=FetchType.LAZY) private Set<Operator> operators = new HashSet<Operator>(); //省略get/set方法 //... }
4)资源(Resource):
/** * 资源 * @author Luxh */ @Entity @Table(name="t_resource") public class Resource { @Id @GeneratedValue private Long id; /**资源名称*/ @Column(length=64) private String name; /**资源代码*/ @Column(length=64) private String code; /**资源描述*/ @Column(length=256) private String description; /**资源URL*/ @Column(length=256) private String url; /**上级资源*/ @ManyToOne @JoinColumn(name="parent_id") private Resource parent; /**下级资源*/ @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY) @JoinColumn(name="parent_id") private Set<Resource> children = new HashSet<Resource>(); /** *哪些角色可以访问 */ @ManyToMany @JoinTable(name="t_resource_role",joinColumns=@JoinColumn(name="function_id"), inverseJoinColumns=@JoinColumn(name="role_id")) private Set<Role> roles = new HashSet<Role>(); /** * 拥有的操作 */ @OneToMany(mappedBy="resource",cascade=CascadeType.ALL,fetch=FetchType.LAZY) private Set<Operator> operators = new HashSet<Operator>(); //省略get/set方法 //... }
5)操作(Operator):
/** * 操作 * @author Luxh */ @Entity @Table(name="t_operator") public class Operator { @Id @GeneratedValue private Long id; /**操作名称*/ @Column(length=64) private String name; /**操作代码*/ @Column(length=64) private String code; /**操作描述*/ @Column(length=256) private String description; /**所属资源*/ @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH}) @JoinColumn(name="resource_id") private Resource resource; /**所属角色*/ @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH}) @JoinColumn(name="role_id") private Role role; //省略get/set方法 //... }
5、JPA生成的数据库表。