spring_cloud_feign服务之间token传递

使用open-feign的拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class FeginInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
try {
Map<String,String> headers = getHeaders();
for(String headerName : headers.keySet()){
requestTemplate.header(headerName, headers.get(headerName));
}
}catch (Exception e){
e.printStackTrace();
}
}
private Map<String, String> getHeaders(){
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Map<String, String> map = new LinkedHashMap<>();
Enumeration<String> enumeration = request.getHeaderNames();
while (enumeration.hasMoreElements()) {
String key = enumeration.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
return map;
}

}

当不开启Hystrix时上面代码生效,当开启Hystrix后不生效,RequestContextHolder.getRequestAttributes()报空指针。这是因为Hystrix默认使用的线程隔离,就是开启一个线程去调用。RequestContextHolder.getRequestAttributes() 内部是使用的ThtreadLocal来获取的,所以需要把值传递给子线程。我们需要使用自定义HystrixConcurrencyStrategy来完成。

1
2
3
4
5
6
@Configuration
public class HystrixConfig {
static {
HystrixPlugins.getInstance().registerConcurrencyStrategy(new RequestContextHystrixConcurrencyStrategy());
}
}

上面这个类是保证自定义类先于默认的策略类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.concurrent.Callable;


public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {

@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
System.out.println("执行到这了");
return () -> {
try {
RequestContextHolder.setRequestAttributes(requestAttributes);
System.out.println("执行到这了2");
return callable.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
};
}
}

鉴权

鉴权是在gatwey网关项目调用认证鉴权中心项目做。获取到用户想访问的连接URL, 如果需要权限,用户有权限,可以访问,用户没有权限,返回无权限。如果地址不需要权限直接可以访问。


spring_cloud_feign服务之间token传递
http://hanqichuan.com/2023/12/05/spring_cloud/spring_cloud_feign服务之间token传递/
作者
韩启川
发布于
2023年12月5日
许可协议