4、自定义权限注解

自定义权限注解

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;
}
posted @ 2022-09-02 18:05  站着说话不腰疼  阅读(308)  评论(0)    收藏  举报