继续,上次我说权限可以分为两大类:操作权限与数据权限。见此篇博文:http://blog.csdn.net/sharetop/article/details/50281669。
Shiro帮我们实现的大多为操作权限,那么今天我想分享一个数据权限的方案,主要采用的仍是注解+切面拦截。
思路大概是这样的:
- 在controller的方法参数,约定包含一个Map类型的parameters
- 通过注解声明一下当前用户的某个成员属性值需要被插入到这个parameters中,并且声明对应的字段名称
- 在方法体中,就可以将parameters中所有成员拿出来生成SQL,实现数据的筛选。
比如,我们需要根据当前登录用户的名称realName,筛选出saleName为当前用户名称的销售数据,又或者,根据当前登录用户的groupNames[0]为北京,筛选出所有数据字段province为北京的计费数据。
首先,我们定义注解 RequiresData,代码如下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresData {
String[] props() default "";
String[] fields() default "";
}
两个属性都是字符串数组,所以我们要使用时可以是这样的:
@RequiresData(props={
"realName","groupNames[0]"},fields={
"saleName","province"})
然后,我们需要修改AuthorizationAttributeSourceAdvisor,同样添加对新注解的支持。
private static final Class<? extends Annotation>[] AUTHZ_ANNOTATION_CLASSES =
new Class[] {
RequiresPermissions.class, RequiresRoles.class,
RequiresUser.class, RequiresGuest.class, RequiresAuthentication.class,
RequiresAction.class,RequiresData.class
};
也同样修改我们继承的AopAllianceAnnotationsAuthorizingMethodInterceptor,添加新的DataAnnotationMet