Mr.姚先森 2022-04-04 23:27 采纳率: 66.7%
浏览 252

关于如何使用注解加上aop实现openfeign内部请求不校验的问题

问题遇到的现象和发生背景

我现在在做一个微服务项目,由于需要内部调用服务,所以想要实现一个注解,这个注解的作用是表明这个方法在内部调用时不需要校验token,然后写一个aspect和一个openfeign的拦截器,实现在openfeign的拦截器中拦截请求判断是否是内部请求,如果是内部请求则不需要传递token直接return,然后会进入到aspect中,判断如果是内部请求直接绕过校验

问题相关代码,请勿粘贴截图

注解:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InnerAuth {
    /**
     * 是否需要校验token
     */
    boolean isNeedAuth() default false;
}
@Component
public class FeignRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        //如果是内部请求,直接return
        Collection<String> fromHeader = requestTemplate.headers().get(SecurityConstants.FROM_SOURCE);
        if (CollUtil.isNotEmpty(fromHeader) && fromHeader.contains(SecurityConstants.INNER)) {
            return;
        }
        HttpServletRequest httpServletRequest = ServletUtils.getRequest();
        if (httpServletRequest == null) {
            return;
        }
        //将当前请求中的所有header加入到新的请求中
        Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
        if (headerNames == null) {
            return;
        }
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            String values = httpServletRequest.getHeader(name);
            requestTemplate.header(name, values);
        }
        //加入token到请求头
        if (StringUtils.isNotNull(httpServletRequest)) {
            String authentication = httpServletRequest.getHeader(TokenConstants.AUTHENTICATION);
            if (!StringUtils.isEmpty(authentication)) {
                if (authentication.contains("false")) {
                    requestTemplate.header(TokenConstants.AUTHENTICATION, "");
                } else {
                    requestTemplate.header(TokenConstants.AUTHENTICATION, authentication);
                }
            }
            // 配置客户端IP
            requestTemplate.header("X-Forwarded-For", IpUtils.getIpAddr(ServletUtils.getRequest()));
        }
        LoggerUtil.info("进入openFeign拦截器,拦截的url为:" + httpServletRequest.getRequestURI());
    }
}
aspect:
```java
@Aspect
@Component
public class InnerAuthAspect implements Ordered {

    @Around("@annotation(innerAuth)")
    public Object innerAround(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable {

        // 实际注入的innerAuth实体由表达式后一个注解决定,即是方法上的@InnerAuth注解实体,若方法上无@InnerAuth注解,则获取类上的
        if (innerAuth == null) {
            Class<?> clazz = point.getTarget().getClass();
            innerAuth = AnnotationUtils.findAnnotation(clazz, InnerAuth.class);
        }
        String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE);
        // 内部请求验证,判断来源或者是否设置了需要验证
        if (!StringUtils.equals(SecurityConstants.INNER, source) || innerAuth.isNeedAuth()) {
            throw new InnerAuthException("没有内部访问权限,不允许访问");
        }
        System.out.println("进入Aop...........");
        return point.proceed();
    }
    /**
     * 确保在权限认证aop执行前执行
     */
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 1;
    }
}
运行结果及报错内容

现在遇到了问题,就是如果内部请求调用服务的时候,header里面是没有token的,这个时候并没有进入到aspect中,而是直接抛出了401异常,就是不知道是没有争取的切入到aspect中去,还是在切入之前就抛出了异常

我想要达到的结果

实现内部调用服务时没有token也可以正常调用

  • 写回答

1条回答 默认 最新

  • a1767028198 2022-04-05 07:39
    关注

    你在调用方搞这些东西是没用的,如果你是oauth2.0,生产者那边如果是资源服务,那就会去检验token,不要token访问,要么资源服务器自己去放行,要么自己去扩展拦截链,对这部分接口做特殊处理

    评论

报告相同问题?

问题事件

  • 创建了问题 4月4日

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题