* permission : 权限
ps : 自我感受写的还算清楚,比较容易理解,不用框架,手动实现好像也...java
一:粗粒度(URL级别权限控制)
id |
url |
1 |
../../xxxQuery |
2 |
../../xxxSave |
3 |
../../xxxUpdate |
4 |
../../xxxDelete |
c_id |
p_id |
1 |
1 |
1 |
2 |
1 |
3 |
1 |
4 |
2 |
1 |
- 能够基于filter实现,当用户访问一个URL地址,查询数据库判断用户当前具备的权限是否包含这个URL,若是包含,容许访问,若是不包含,则权限不足
二:细粒度(方法级别权限控制)
id |
desc |
1 |
xxx_query |
2 |
xxx_save |
3 |
xxx_update |
4 |
xxx_delete |
c_id |
p_id |
1 |
1 |
1 |
2 |
1 |
3 |
1 |
4 |
2 |
1 |
@Permission("xxx_save")
save(){
dao.save();
}
- 咱们经过在方法上添加自定义注解,这个注解能够描述权限信息,当咱们要访问目标对象的方法时,对目标对象建立代理对象,经过反射拿到权限描述,在代理对象中查询数据库判断其是否具备注解上描述的权限,若是有该访问权限,则访问目标对象的方法,反之则拦截,并提示权限不足
三:权限控制常规模型(5张表)
(一)表结构
- 用户
(User)
字段 |
类型 |
描述 |
id |
Integer |
主键 |
name |
String |
用户姓名 |
... |
... |
其余 |
- 角色
(role)
字段 |
类型 |
描述 |
id |
Integer |
主键 |
name |
String |
角色名称 |
keyword |
String |
角色关键字,用于权限控制 |
description |
String |
描述 |
- 用户角色中间表
(user_role)
字段 |
类型 |
描述 |
user_id |
Integer |
用户ID |
role_id |
Integer |
角色ID |
- 权限
(permission)
字段 |
类型 |
描述 |
id |
Integer |
主键 |
name |
String |
权限名称 |
keyword |
String |
权限关键字,用于权限控制 |
description |
String |
描述 |
- 角色权限中间表
(role_permission)
字段 |
类型 |
描述 |
role_id |
Integer |
角色ID |
permission_id |
Integer |
权限ID |
(二)简单聊一下角色表
- 咱们发现这五张表(三张主表)是以角色为中心分别以多对多的形式关联用户和权限,而不是由用户和权限直接关联,这并非说用户和权限直接关联不能够,只是为了方便咱们对用户进行受权
- 打个比方:陆军上将能够管陆军,空军上将能够管空军,海军上将能够管海军,若是你是陆海空三军上将,是否是什么兵均可以管了呢?
- 也就是说,咱们为用户分配角色,为角色分配权限,从而达到为用户分配权限的目的,角色的存在就是为了方便对用户受权也能够理解为,角色就是权限的集合
(三)补充:动态菜单管理
- 在后台管理系统中,咱们一般须要进行动态菜单管理,即为不一样的用户指定不一样的系统菜单
- 菜单表
(menu)
字段 |
类型 |
描述 |
id |
Integer |
主键 |
name |
String |
菜单名称 |
page |
String |
访问路径 |
priority |
Integer |
优先级 |
description |
String |
描述 |
- 咱们仍然不直接和用户关联,那样太累了,咱们选择经过角色进行管理(其实就是粗粒度url控制)
- 角色菜单表
(role_menu)
字段 |
类型 |
描述 |
role_id |
Integer |
角色ID |
menu_id |
Integer |
菜单ID |