数据(行)权限 #
1. 简单举例 #
数据权限也是数据行权限,根据用户的不同的身份在不改变sql以及其他代码的情况下,通过动态的生成不同的sql来完成获取不同的数据。
以下只是一个简单举例,更多详细内容之后会补充
java
@BatchAuthData({
// (1) 订单,可以由本人查看
@AuthData(requireRoles = {"销售人员"},
condition = "id={userId}"),
// (1) 销售单,销售人员可以查看自己的,销售经理只查看销售金额大于100,000的或者小于4000的。
@AuthData(requireRoles = {"销售人员", "销售经理"},
condition = "id={userId} or ( {userId} in {销售经理Id} and (amount > 100000 or amount < 4000) )"),
// (2) 销售单,销售人员可以查看自己的,上级领导查看也能查看,销售经理只查看销售金额大于100,000的或者小于4000的。
@AuthData(requireRoles = {"销售人员", "销售经理", "领导"},
condition = "id={userId} or {userId} in {领导Id} or ( {userId} in {销售经理Id} and (amount > 100000 or amount < 4000) )"),
// (1)普通员工(仅能看到自己的信息)
@AuthData(requireRoles = "普通员工",
condition = "id={userId}"),
//(2)部门管理人(仅能看到本部门)
@AuthData(requireRoles = {"部门管理人员"},
condition = "dept in {本部门Id}",
args = @Arg(resource = "本部门Id", args = "{currentUserId}")),
//(3)分公司董事(其他分公司所有的部门,除了董事会部门)
@AuthData(requireRoles = {"分公司董事"},
condition = "orgId in {其他分公司} and dept not in {董事会部门}",
args = {
@Arg(resource = "其他分公司", args = "{userId}"),
@Arg(resource = "董事会部门", args = "{其他分公司}")
}
),
//(4)分公司总负责人(看到分公司所有的信息)
@AuthData(requireRoles = {"分公司总负责人"},
condition = "orgId in {其他分公司}",
args = {
@Arg(resource = "其他分公司", args = "{userId}")
}
),
//(5)总公司董事会(除了总公司董事会之外的所有总,自公司的所有部门)
@AuthData(requireRoles = {"总公司董事会"},
condition = "dept not in {董事会部门}",
args = @Arg(resource = "董事会部门")
),
//(6)总董事
@AuthData(requireRoles = "总董事"),
// (1) admin可以查看 username为 201803010224 201803010212 201803010222
@AuthData(requireRoles = "admin", condition = "username in (201803010224,201803010212,201803010222)"),
@AuthData(requireRoles = {"admin", "user"}, condition = "username in (201803010213)"),
// ==> admin 可以看到 201803010224、201803010212、201803010222、201803010213
})
@AuthData(requireRoles = {"分公司董事"},
condition = "orgId in #{其他分公司} and dept not in #{董事会部门}",
args = {
@Arg(resource = "其他分公司", args = "#{userId}"),
@Arg(resource = "董事会部门", args = "#{其他分公司}")
}
)
@Data
public class AuthzDataTest {
}
2. ArgResource #
如上的#{xxx}还有之前在参数权限里面的#{id}等都是一个参数资源。这是一个动态的值,和spring的SpEL不同,ArgResource是一个简单的,快速的资源,可以直接定位到某个方法,而不需要再写很长的表达式
在方法上用注解ArgResource标记静态方法或者bean的方法,都可以实现资源申请。
- 标记静态方法
java
public class TestArgResource {
@ArgResource(description = "id") // 默认为方法名
public static int id() {
return 1;
}
}
- 标记bean的方法
java
@Service
public class UserService extends ServiceImpl<UserMapper, User>
implements IUserService {
@ArgResource("所有用户") // 在数据权限和参数权限中可以 #{所有用户}这样使用
@Roles("admin")
public List<User> ls() {
return list();
}
}
注意
若标记在了需要权限才能访问的方法上时,会优先检查权限是否满足。
3. 默认的ArgResource #
在Authz内有3个默认的参数
- userId - 当前用户id
- token - 当前用户的token
- httpMeta - 当前请求的元信息
4. AuthzResourcesScan #
最后也是最重要的一点,如果想让资源扫描生效,数据权限、以及后续的字段权限生效,需要加上注解AuthzResourcesScan
其中的entity为数据权限所绑定的实体类所在包路径,可以指定多个,
其中的args为资源所在的包路径
java
@AuthzResourcesScan(entity = "cn.omisheep.authz.demo.entity",
args = {"cn.omisheep.authz.demo.service",
"cn.omisheep.authz.demo.mapper"})