首页 > 其他分享 >自定义权限注解

自定义权限注解

时间:2022-09-02 18:11:16浏览次数:52  
标签:null 自定义 clazz findAnnotation AnnotationUtils import 注解 权限 class

目录

自定义权限注解

1、新增一个注解

ps:此注解可以作用到类上或方法上

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;

@Target({ElementType.METHOD,ElementType.TYPE}) //可作用到类上或方法上
@Retention(RetentionPolicy.RUNTIME)//运行时注解
@Documented//表明这个注解应该被 javadoc工具记录
public @interface PermissionRequest {
    /**默认是获取拦截路径
    **@return
    */
    boolean required() default true;  //默认值true:拦截   false:放行
}

2、增加一个bean监听处理器

ps: 在spring容器加载完bean后查看上面是否有注解,如果有存到redis上

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.beans.BeansException;
import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class PermissionRequestProcessor implements BeanPostProcessor {

    protected final Logger LOG = LoggerFactory.getLogger(getClass());

    @Autowired
    protected RedisTemplate<String, Object> jsonRedisTemplate;

    private List<String> openRequestPath = new ArrayList<>();

    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    SpringContextUtil springContextUtil;

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

        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> clazz = bean.getClass();
        Controller controllerIs = AnnotationUtils.findAnnotation(clazz, Controller.class);
        RestController restControllerIs = AnnotationUtils.findAnnotation(clazz, RestController.class);
        if (controllerIs != null || restControllerIs != null) {
            //获取类上的注解
            PermissionRequest clazzOpenRequestIs = AnnotationUtils.findAnnotation(clazz, PermissionRequest.class);

            Boolean classPermissionIs = false;
            if (clazzOpenRequestIs != null) {
                classPermissionIs = true;
            }
            this.getMethodUri(clazz, classPermissionIs);

            if (openRequestPath.size() > 0) {

                HashOperations<String, Object, Object> hash = jsonRedisTemplate.opsForHash();
                ApplicationContext applicationContext = SpringContextUtil.getApplicationContext();
                Environment environment = applicationContext.getBean(Environment.class);
                String property = environment.getProperty("spring.application.name");
                hash.put(RedisKeyConstant.SYS_OPEN_REQUEST_PATH, StringUtils.upperCase(property), openRequestPath);
            }
        }
        return bean;
    }

    private void getMethodUri(Class<?> clazz, Boolean classPermissionIs) {
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {

            PermissionRequest sysOpenRequestIs = null;

            if (!classPermissionIs) {
                sysOpenRequestIs = AnnotationUtils.findAnnotation(method, PermissionRequest.class);
            }

            if (classPermissionIs || (sysOpenRequestIs != null && !sysOpenRequestIs.required())) {
                List<Annotation> classAnnotations = this.getAnnotations(clazz);
                StringBuffer fath = lookupRequestMappingPath(classAnnotations);
                List<Annotation> methodAnnotations = this.getAnnotations(method);
                if (methodAnnotations != null && methodAnnotations.size() > 0) {
                    StringBuffer path =lookupRequestMappingPath(methodAnnotations);
                    path = fath.append(path);
                    //LOG.info("Request entry ->{path:{}}", path);
                    openRequestPath.add(path.toString());
                }
            }
        }
    }

    private List<Annotation> getAnnotations(Method method) {
        List<Annotation> methodAnnotations = new ArrayList<>();

        RequestMapping isMethodRequestMapping = AnnotationUtils.findAnnotation(method, RequestMapping.class);
        GetMapping methodGetMapping = AnnotationUtils.findAnnotation(method, GetMapping.class);
        PostMapping methodPostMapping = AnnotationUtils.findAnnotation(method, PostMapping.class);
        DeleteMapping methodDeleteMapping = AnnotationUtils.findAnnotation(method, DeleteMapping.class);
        PutMapping methodPutMapping = AnnotationUtils.findAnnotation(method, PutMapping.class);

        if (isMethodRequestMapping != null) {
            methodAnnotations.add(isMethodRequestMapping);
        }

        if (methodGetMapping != null) {
            methodAnnotations.add(methodGetMapping);
        }

        if (methodPostMapping != null) {
            methodAnnotations.add(methodPostMapping);
        }

        if (methodDeleteMapping != null) {
            methodAnnotations.add(methodDeleteMapping);
        }

        if (methodPutMapping != null) {
            methodAnnotations.add(methodPutMapping);
        }

        return methodAnnotations;
    }

    private List<Annotation> getAnnotations(Class clazz) {
        List<Annotation> classAnnotations = new ArrayList<>();

        RequestMapping isClassRequestMapping = AnnotationUtils.findAnnotation(clazz, RequestMapping.class);
        GetMapping classGetMapping = AnnotationUtils.findAnnotation(clazz, GetMapping.class);
        PostMapping classPostMapping = AnnotationUtils.findAnnotation(clazz, PostMapping.class);
        DeleteMapping classDeleteMapping = AnnotationUtils.findAnnotation(clazz, DeleteMapping.class);
        PutMapping classPutMapping = AnnotationUtils.findAnnotation(clazz, PutMapping.class);

        if (isClassRequestMapping != null) {
            classAnnotations.add(isClassRequestMapping);
        }

        if (classGetMapping != null) {
            classAnnotations.add(classGetMapping);
        }

        if (classPostMapping != null) {
            classAnnotations.add(classPostMapping);
        }

        if (classDeleteMapping != null) {
            classAnnotations.add(classDeleteMapping);
        }

        if (classPutMapping != null) {
            classAnnotations.add(classPutMapping);
        }
        return classAnnotations;
    }

    private StringBuffer lookupRequestMappingPath(List<Annotation> annotations) {
        if (annotations == null || annotations.size() <= 0) {
            return null;
        }
        String[] paths = null;
        if (annotations.size() == 1) {
            paths = (String[]) AnnotationUtils.getValue(annotations.get(0));
        } else {
            paths = (String[]) AnnotationUtils.getValue(annotations.get(1));
        }

        if(paths == null || paths.length <= 0){
            return null;
        }
        else{
            return paths[0].startsWith("/") ? new StringBuffer(paths[0]) : new StringBuffer('/'+paths[0]);
        }
    }
}

3、使用注解

ps: 默认为true拦截请求,false不拦截

@ApiOperation(value = "根据id查询参数信息")
@RequestMapping(value = "/find_by_id/{id}", method = RequestMethod.GET)
@PermissionRequest(required = false)
public BaseResponse<SysConfigVo> findById(@PathVariable("id") Long id) {
	SysConfigVo sysConfigVo = sysConfigService.findById(id);
	return new BaseResponse<SysConfigVo>(ResCodeConstant.RESCODE_SUCCESS, sysConfigVo);
}

4、网关中对开放的路径放行

ps:在网关拦截和放行登录权限中,增加判断

/**
 *
 * 获取开放权限校验
 * @param var1
 * @return
 */

private Boolean isOpenPermission(HttpServletRequest var1){
    if(Boolean.TRUE.equals(!this.redisTemplate.hasKey(RedisKeyConstant.SYS_OPEN_REQUEST_PATH))){
        return false;
    }
    UrlPathHelper urlPathHelper = new UrlPathHelper();
    Route matchingRoute = routeLocator.getMatchingRoute(urlPathHelper.getPathWithinApplication(var1));

    //跳转应用
    String applicationName = StringUtils.upperCase(matchingRoute.getLocation());
    //跳转url
    String path = matchingRoute.getPath();

    if(path == null){
        return false;
    }
    HashOperations<String, Object, Object> opsForHash = this.redisTemplate.opsForHash();

    List<String> openRequestPaths = (List<String>)opsForHash.get(RedisKeyConstant.SYS_OPEN_REQUEST_PATH, applicationName);
    if(openRequestPaths == null ){
        return false;
    }
    for (String openRequestPath : openRequestPaths) {
        if(openRequestPath != null && this.pathMatcher.match(openRequestPath,path)){
            return true;
        }
    }
    return false;
}

标签:null,自定义,clazz,findAnnotation,AnnotationUtils,import,注解,权限,class
From: https://www.cnblogs.com/lgxdev/p/16650864.html

相关文章

  • spring注解开发
    @Componet组件,放在类上,说明这个类被spring管理了,就是bean类前加这个注解,相当于bean等价于<beanid="xxx"class="xxxxxx"/>名字默认是类的名字的小写@Value("xxx")相......
  • 自定义注解+aop做日志记录
    自定义一个注解:@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public@interfaceCommitLog{/***类型名称*@retu......
  • springboot 自定义注解拦截器
    参考:https://blog.csdn.net/mxlgslcd/article/details/89155315第一步:自定义注解@Target(ElementType.METHOD)//可用在方法名上@Retention(RetentionPolicy.RUNTIME)/......
  • [Spring框架]spring新注解配置、spring整合JUnit5
    1.spring新注解配置1.@Configuration作用:配置类,等同于bean.xml文件获取容器时需要使用AnnotationApplicationContext(有@Configuration注解的类.class)属性:value:指定配......
  • 基于函数计算自定义运行时快速部署一个 springboot 项目 什么是函数计算?
    什么是函数计算?函数计算是事件驱动的全托管计算服务。使用函数计算,您无需采购与管理服务器等基础设施,只需编写并上传代码。函数计算为您准备好计算资源,弹性地可靠地运行任......
  • ubuntu20.04开启root权限登陆
     1、使用普通用户登录后切换root1sudo-i 2、修改root的密码1echoroot:123123|sudochpasswdroot  3、开启root登录1sudosed-i's/^#\?PermitR......
  • elementui对于vue表单自定义校验
    在<el-form-itemlabel="原因"prop="reson":rules="条件==值?[{required:true,message:'原因不能为空',trigger:'blur'}]:[{requ......
  • 使用 CSS 自定义鼠标光标
    使用CSS自定义鼠标光标你好,互联网上令人惊叹的人。希望你们都做得很好。在本文中,我们将讨论CSS光标属性。我们将在这里看到有多少类型的值与可用的游标属性相关联。......
  • 21 | JAVA注解
    注解什么是注解(Annotation)?注解是放在Java源码的类、方法、字段、参数前的一种特殊“注释”:Java的注解可以分为三类:第一类是由编译器使用的注解,例如:@Override:让编译器检......
  • 自定义分页器
    自定义分页器针对上一小节批量插入的数据,我们在前端展示的时候发现一个很严重的问题,一页展示了所有的数据,数据量太大,查看不方便针对数据量大但又需要全部展示给用户观看......