spring+shiro+自定义注解实现 数据层权限控制
博客专区 > Hccake 的博客 > 博客详情
spring+shiro+自定义注解实现 数据层权限控制
Hccake 发表于10个月前
spring+shiro+自定义注解实现 数据层权限控制
  • 发表于 10个月前
  • 阅读 43
  • 收藏 2
  • 点赞 1
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

数据层权限控制  本来是想利用springMvc的拦截器来做到数据过滤  
在进入方法之前   根据shiro权限来修改request中传过来的对应参数

后来几经尝试都没有成功   因为requsest中的parameter是不可修改的   即使重新定义了一个新的request
又找不到和过滤器一样的放行方法     后来还是采用了的springAOP 的环绕通知
 

 

首先定义一个作用在方法上的注解 :

package cn.moppo.domino.web.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
 * 数据权限过滤注解  实现数据层权限过滤
 * @author Hccake
 *
 */
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataScreening {
	
	/**
	 * 过滤的pojo类名  
	 */
	Class<?> value();
	/**
	 * 过滤参数
	 * @return
	 */
	String[] fields() default {};
}

 在需要做权限控制的方法上加上该注解:

定义切面:

package cn.web.filter;

import java.lang.reflect.Method;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import cn.model.User;
import cn.utils.Utils;
import cn.web.annotation.DataScreening;
import cn.web.utils.UserUtils;


@Aspect
public class DataAspectj {

	//定义切点DataScreening注解
    @Pointcut("@annotation(cn.web.annotation.DataScreening)")
    public void cutDataScreening(){
        
    }


    //环绕通知
    @Around("cutDataScreening()")
    public Object dataScreen(ProceedingJoinPoint point) throws Throwable{
    	
    	//获取当前执行方法上的  DataScreening注解
        Signature signature = point.getSignature();    
        MethodSignature methodSignature = (MethodSignature)signature;    
        Method targetMethod = methodSignature.getMethod();    
        DataScreening dc = targetMethod.getAnnotation(DataScreening.class);
        
        //获取被权限控制的pojo类型
        Class<?> pojoClass = dc.value();
        String className = pojoClass.getSimpleName();
        
        //注解参数   需要过滤的数据字段的集合
        String[] fields = dc.fields();
        //获取登录用户
        User loginUser = UserUtils.getLoginUser();
        Subject loginSubject = SecurityUtils.getSubject();
       
        
        //方法传入的所有参数
        Object[] args = point.getArgs();
        
        //找到参数列表中对应需要权限控制的参数的角标)
        //没有用index直接作为角标循环是为了    保留扩展  可能会没有封装成对象   但是有xxxStr等 请求参数
        Integer index = null;
        for (int i = 0; i < args.length; i++) {
			if(pojoClass.isInstance(args[i])){
				index = i;
				break;
			}
		}
        //获取参数
        Object obj = args[index];
        
        
        //***********************字段数据过滤**********************************
        if(fields != null && fields.length != 0){
            for (String field : fields) {
				
            	//在此根据shiro 以及业务做数据过滤操作				
			}
        }
        

        
        
    	//重新定义参数
        args[index] = obj;
        //传入新的参数  并执行切入点的方法
    	Object retVal = point.proceed(args);
        //返回结果  若被注解方法都是void 可以不执行return
        return retVal;
    }
}

 

在配置文件中加入切面    

 关于配置文件的引入顺序是有讲究的   在ream认证的时候是否能使用spring自动注入的bean  具体情况具体配置   具体容器初始化配置请看   https://my.oschina.net/hccake/blog/873958

  <bean id="dataAspectj" class="cn.web.filter.DataAspectj" />
	   <aop:aspectj-autoproxy proxy-target-class="true">
	   	<aop:include name="dataAspectj" />
</aop:aspectj-autoproxy>

 

共有 人打赏支持
粉丝 0
博文 24
码字总数 6189
×
Hccake
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: