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

关于如何使用注解加上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条回答 默认 最新

相关推荐 更多相似问题