Originally raised by @Ayesha-Hyath at https://github.com/spring-projects/spring-boot/issues/23049
@Override
public String getToken() {
HttpServletRequest request = httpRequest.getIfAvailable();
if (request == null) {
throw new IllegalStateException("No HttpServletRequest available");
}
String token = request.getHeader(ConfigClientProperties.TOKEN_HEADER);
if (!StringUtils.hasLength(token)) {
throw new IllegalArgumentException(
"Missing required header in HttpServletRequest: "
+ ConfigClientProperties.TOKEN_HEADER);
}
return token;
}
The above method is from the HttpRequestConfigTokenProvider class.
We use a Spring Config Server that connects both to Vault and a Git Repository. So, it's bootstrap file has the entry: spring.profiles.active=git, vault. We have a Spring Boot app that connects to this Config Server. I am using the property spring.cloud.config.headers.X-Config-Token=vault token in the bootstrap file of the Spring Boot app and the application starts up fine. It is to be noted that during start-up, the EnvironmentController class is called as also the HttpRequestConfigTokenProvider .getToken() method and each time the token gets sent from the application to the Config Server as can be noted from the attached screenshot.
I use a ReloadableResourceBundleMessageSource to load a required properties file from the Git Repository.. When I call messageSource.getMessage(code, args, locale), the following mapping from the ResourceController class is invoked in the Config Server.
@RequestMapping("/{name}/{profile}/{label}/**")
public String retrieve(@PathVariable String name, @PathVariable String profile,
@PathVariable String label, ServletWebRequest request,
@RequestParam(defaultValue = "true") boolean resolvePlaceholders)
throws IOException {
String path = getFilePath(request, name, profile, label);
return retrieve(request, name, profile, label, path, resolvePlaceholders);
}
Subsequently, the same HttpRequestConfigTokenProvider.getToken() method gets invoked but, now, it returns a null token.
The messages from the git repository get loaded properly under two scenarios: 1. I remove vault and only use git as an active profile in the Config Server bootstrap file (this is not an option. I just did for testing.) OR 2. I specify the Vault Token in the Config Server bootstrap file instead of passing it from the Spring Boot application. (this is not an option either. I did it just for testing.)
However, I am unable to load the messages similarly only if I pass the vault token from the Spring Boot application that already has the header X-Config-Token set in both the bootstrap and the application.properties files (added here for testing). Before calling the getMessage(..) on the messageSource, I do a env.get(spring.cloud.config.headers.X-Config-Token) and the token value gets printed. However, the HttpRequestConfigTokenProvider.getToken() method returns null instead of the vault token header value and thus, the properties do not get loaded and the call fails with the attached error trace.
ErrorTraceInTheConfigServerApplication.txt
ErrorTraceInTheSpringBootApplication.txt
Comment From: spencergibb
Trying to understand. You have a ReloadableResourceBundleMessageSource
that makes a call to config server and it fails because it doesn't have the proper vault token? I'd assume that is because the ReloadableResourceBundleMessageSource
doesn't know anything about the token.
Comment From: Ayesha-Hyath
Yes. Exactly, that's right. The ReloadableResourceBundleMessageSource knows the token when I pass it directly in the bootstrap.properties of the config server.
I have an application that connects to the config server which then connects to Vault. This time, I pass the vault token from the application's bootstrap file and it does get passed. However, it gets lost by the time the config server tries to validate for the token, as can be noted from my attached screenshots in the bug report. Hence, the message source doesn't get loaded.
If I pass the vault token instead in the config server, the same message source gets loaded.
Thanks, Ayesha Fathima Hyath,
On Wed, Feb 17, 2021 at 11:10 PM Spencer Gibb notifications@github.com wrote:
Trying to understand. You have a ReloadableResourceBundleMessageSource that makes a call to config server and it fails because it doesn't have the proper vault token? I'd assume that is because the ReloadableResourceBundleMessageSource doesn't know anything about the token.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/spring-cloud/spring-cloud-config/issues/1688#issuecomment-780727643, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQWJ3Q2EQIU22RPH3E762BDS7P5RPANCNFSM4QIHBAXQ .
Comment From: spencergibb
I would assume you'd need to write something custom on the client that knows how to send the token. Probably a ResourceLoader
that can be set on ReloadableResourceBundleMessageSource
. Looks like there is already an open issue for this support here #1505. Closing this as a duplicate.