基于拦截器的用自定义注解进行权限拦截

对于增删改接口,管理员权限能操作,用户权限不能操作.

1. 定义一个注解类

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface RoleOfAdmin {

    String value() default "admin";

}

2.重写BeanPostProcessor,在spring创建bean之后,在自建的容器中存储有自定义注解的bean信息

@Component
public class AuthorityControllerBeanProcessor implements BeanPostProcessor {


    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        Class clazz = bean.getClass();
        Boolean isControllerAnnotationInClass = clazz.isAnnotationPresent(Controller.class) || clazz.isAnnotationPresent(RestController.class);

        if (isControllerAnnotationInClass) {
            // 如果这是一个 Controller Bean 的话
            // 那么就读取所有方法的权限配置
            Method[] methods = ReflectionUtils.getAllDeclaredMethods(bean.getClass());

            for (Method method : methods) {

                Boolean isAuthorityAnnotationInMethod = method.isAnnotationPresent(RoleOfAdmin.class);
                if (isAuthorityAnnotationInMethod) {
                    // 如果有 @Authority 注解的话
                    // 则记录该注解中的内容
                    String target = bean.getClass().getName() + "." + method.getName();
                    RoleOfAdmin annotation = method.getAnnotation(RoleOfAdmin.class);
                    AuthorityAnnotationContainer.set(target,annotation);
                }
            }

            return bean;
        } else {
            // 否则的话直接返回Bean
            return bean;
        }
    }

}

3. 建的存储有自定义注解bean信息的容器

public class AuthorityAnnotationContainer {


    public static ConcurrentHashMap<String,Object> ROLE_MAP =new ConcurrentHashMap<String,Object>() ;


    public static void  set(String target, RoleOfAdmin roleOfAdmin){
        ROLE_MAP.put(target,roleOfAdmin);
    }

    public static void  remove(String target){
        ROLE_MAP.remove(target);
    }

    public static RoleOfAdmin  get(String target){
        RoleOfAdmin roleOfAdmin = (RoleOfAdmin) ROLE_MAP.get(target);
        return roleOfAdmin;
    }

}

4. 配置一个拦截器,用来获取controller里方法上的自定义注解. 如果有该注解,会从Threadlocal里拿到用户权限信息,这个用户权限信息是在这个拦截器之前的一个身份拦截器里获取到的,代码详见另一篇文章 文章地址

@Component
public class AuthorityInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {



        // 将handler强转为HandlerMethod, 前面已经证实这个handler就是HandlerMethod
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 从方法处理器中获取出要调用的方法
        Method method = handlerMethod.getMethod();

        String target = handlerMethod.getBean().getClass().getName() + "." + method.getName();

        RoleOfAdmin roleOfAdmin = AuthorityAnnotationContainer.get(target);

        if(roleOfAdmin != null){

            OssAdmin currentUser = RequestHolder.getCurrentUser();
            if(currentUser.getRole().contains(MainConstants.SYS)){
                return true;
            }else {

                PrintWriter printWriter = response.getWriter();
                ApiResult result = new ApiResult<>();
                result.setCode(CommonCode.TOKEN_INVALID.getKey());
                result.setMsg("用户无权限");
                printWriter.write(result.toString());
                return false;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

5. 拦截器配置类

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {

    @Autowired
    RedisFeignClient redisFeignClient;


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //通用拦截器,用来允许跨域请求
        registry.addInterceptor(new CommonInterceptor()).addPathPatterns("/**");

        // cookie拦截器,用来获取cookie信息,如果验证了cookie,会向RequestHolder里塞入用户信息
        registry.addInterceptor(new TokenIntecptor(redisFeignClient)).addPathPatterns("/**")
                // 排除用户登录
                .excludePathPatterns("/ossadmin/login")
                .excludePathPatterns("/ossadmin/logout")
               
        registry.addInterceptor(new AuthorityInterceptor()).addPathPatterns("/**")
                // 排除用户登录
                .excludePathPatterns("/ossadmin/login")
                .excludePathPatterns("/ossadmin/logout")
               

    }


  

   }

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值