问题遇到的现象和发生背景
我现在在做一个微服务项目,由于需要内部调用服务,所以想要实现一个注解,这个注解的作用是表明这个方法在内部调用时不需要校验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也可以正常调用