我们在kubeneters集群中有8个Java微服务相互通信。每个微服务都与身份验证库捆绑在一起,身份验证库针对向控制器的每个REST请求拦截并验证/更新JWT令牌。
场景: 从Frontend,我们第一次获得访问令牌,身份验证成功。可以说
问题:我必须将相同的访问令牌从“ A”传递到“ B”,但我无法在Controller / Service逻辑中获取访问令牌,而只能在正在验证令牌的过滤器中获取。通过在控制器的所有rest方法中添加以下参数,可以在Rest Controllers中获得令牌:
@RequestHeader (name="Authorization") String token
但是我不想采用这种方法,因为我必须将此令牌传递到任何地方直到结束,并且必须在所有APIS中声明此参数。
我想通过传递身份验证对象从TokenStore获得令牌。我们正在使用Oauth2,我检查了库中的代码,有很多tokenStore提供程序。
在DefaultTokenServices.java类中,我正在呼叫
Authentication auth = SecurityContextHolder.getContext().getAuthentication() // Passed this auth to tokenStore
String token = tokenStore.getAccessToken(auth).getValue(); // NullPointerException
我的代码正在通过JWTTokenStore提供程序,该提供程序返回null。我检查了一下,有一个名为InMemoryTokenStore.class的提供程序,它实际上从商店中提取了令牌。但是我的流程并没有涉及到内存实现。
有什么方法可以让我事后获得令牌,而无需通过参数在控制器中获取令牌吗?或如何启用/使用inMemoryTokenStore?
还推荐一些更好的kubernetes互通身份验证吗?
TIA
答案 0 :(得分:1)
您似乎正在使用Spring(和Spring Security),所以我认为文档的相关部分是Bearer Token Propagation上的部分。
它的建议是使用WebClient
(从Spring 5开始,建议RestTemplate
的替代品)使用提供的ServletBearerExchangeFilterFunction
将JWT令牌从传入请求自动传播到传出请求:
@Bean
public WebClient rest() {
return WebClient.builder()
.filter(new ServletBearerExchangeFilterFunction())
.build();
}
在RestTemplate
上,文档说:
“目前尚无对RestTemplate的专门支持,但您可以使用自己的拦截器非常简单地实现传播”
,并提供以下示例:
@Bean
RestTemplate rest() {
RestTemplate rest = new RestTemplate();
rest.getInterceptors().add((request, body, execution) -> {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
return execution.execute(request, body);
}
if (!(authentication.getCredentials() instanceof AbstractOAuth2Token)) {
return execution.execute(request, body);
}
AbstractOAuth2Token token = (AbstractOAuth2Token) authentication.getCredentials();
request.getHeaders().setBearerAuth(token.getTokenValue());
return execution.execute(request, body);
});
return rest;
}
如果您要尝试传播令牌,我不认为您需要查看TokenStore
。请记住,与JWT相关的所有内容都应位于令牌本身内。 (这就是为什么the doc for the JwtTokenStore解释说它实际上不存储任何内容,而是从令牌中提取信息的原因,并且对于某些方法(包括您正在调用的getAccessToken()
方法)将返回null。)