How to get bearer token from header of a request in java spring boot?
An easy way to get Bearer Token from the header is to use @RequestHeader with the header name.
See code sample below
@PostMapping("/some-endpoint")
public ResponseEntity<String> someClassNmae(@RequestHeader("Authorization") String bearerToken) {
System.out.println(bearerToken); // print out bearer token
// some more code
}
Although the suggested answers work, passing the token each time to FeignClient
calls still not the best way to do it.
I would suggest to create an interceptor for feign requests and there you can extract the token from RequestContextHolder
and add it to request header directly.
like this:
@Component
public class FeignClientInterceptor implements RequestInterceptor {
private static final String AUTHORIZATION_HEADER = "Authorization";
public static String getBearerTokenHeader() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader("Authorization");
}
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header(AUTHORIZATION_HEADER, getBearerTokenHeader());
}
}
this way you have a clean solution for your issue
You have several options here.
For example, you can use a request scoped bean and, as you suggest, one MVC interceptor.
Basically, you need to define a wrapper for the token value:
public class BearerTokenWrapper {
private String token;
// setters and getters
}
Then, provide an implementation of an MVC HandlerInterceptor
:
public class BearerTokenInterceptor extends HandlerInterceptorAdapter {
private BearerTokenWrapper tokenWrapper;
public BearerTokenInterceptor(BearerTokenWrapper tokenWrapper) {
this.tokenWrapper = tokenWrapper;
}
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
final String authorizationHeaderValue = request.getHeader("Authorization");
if (authorizationHeaderValue != null && authorizationHeaderValue.startsWith("Bearer")) {
String token = authorizationHeaderValue.substring(7, authorizationHeaderValue.length());
tokenWrapper.setToken(token);
}
return true;
}
}
This interceptor should be registered in your MVC configuration. For instance:
@EnableWebMvc
@Configuration
public class WebConfiguration extends WebConfigurer { /* or WebMvcConfigurerAdapter for Spring 4 */
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(bearerTokenInterceptor());
}
@Bean
public BearerTokenInterceptor bearerTokenInterceptor() {
return new BearerTokenInterceptor(bearerTokenWrapper());
}
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public BearerTokenWrapper bearerTokenWrapper() {
return new BearerTokenWrapper();
}
}
With this setup, you can use the bean in your Service
autowiring the corresponding bean:
@Autowired
private BearerTokenWrapper tokenWrapper;
//...
public TransDeliveryPlanning save(InputRequest<TransDeliveryPlanningDto> request) {
Future<List<PartnerDto>> initPartners = execs.submit(getDataFromAccount(transDeliveryPlanningDtSoDtoPartnerIdsSets));
}
public Callable<List<PartnerDto>> getDataFromAccount(Set<Long> ids) {
String tokenString = tokenWrapper.getToken();
List<PartnerDto> partnerDtoResponse = accountFeignClient.getData("Bearer " + tokenString, ids);
return () -> partnerDtoResponse;
}
Similar solutions has been provided here in stack overflow. See, for instance, this related question.
In addition to this Spring based approach, you can try something similar to the solution exposed in this other stackoverflow question.
Honestly I have never tested it, but it seems that you can provide the request header value right in the Feign client definition, in your case something like:
@FeignClient(name="AccountFeignClient")
public interface AccountFeignClient {
@RequestMapping(method = RequestMethod.GET, value = "/data")
List<PartnerDto> getData(@RequestHeader("Authorization") String token, Set<Long> ids);
}
Of course, you can also a common Controller
that other Controller
s can extend. This Controller
will provide the logic necessary to obtain the bearer token from the Authorization
header and the HTTP request provided, but in my opinion any of the aforementioned solutions are better.