Hi what trying to achieve is to get bearer token that submited from front end in java spring boot RESTApi controller and do another request using feign client to another microservices? here is what i do
image above is how i do my request from postman, and here is my controller code :
@Operation(summary = "Save new")
@PostMapping("/store")
public ResponseEntity<ResponseRequest<TransDeliveryPlanning>> saveNewTransDeliveryPlanning(
@Valid @RequestBody InputRequest<TransDeliveryPlanningDto> request) {
TransDeliveryPlanning newTransDeliveryPlanning = transDeliveryPlanningService.save(request);
ResponseRequest<TransDeliveryPlanning> response = new ResponseRequest<TransDeliveryPlanning>();
if (newTransDeliveryPlanning != null) {
response.setMessage(PESAN_SIMPAN_BERHASIL);
response.setData(newTransDeliveryPlanning);
} else {
response.setMessage(PESAN_SIMPAN_GAGAL);
}
return ResponseEntity.ok(response);
}
and here is how my service look like :
public TransDeliveryPlanning save(InputRequest<TransDeliveryPlanningDto> request) {
Future<List<PartnerDto>> initPartners = execs.submit(getDataFromAccount(transDeliveryPlanningDtSoDtoPartnerIdsSets));
}
public Callable<List<PartnerDto>> getDataFromAccount(Set<Long> ids) {
String tokenString = "i should get the token from postman, how do i get it to here?";
List<PartnerDto> partnerDtoResponse = accountFeignClient.getData("Bearer " + tokenString, ids);
return () -> partnerDtoResponse;
}
as you can see, in "tokenString" there i put a string that i questioned about, how do i get it to there from postman?
Bearer tokens enable requests to authenticate using an access key, such as a JSON Web Token (JWT). The token is a text string, included in the request header. In the request Authorization tab, select Bearer Token from the Type dropdown list. In the Token field, enter your API key value.
To send a request with the Bearer Token authorization header, you need to make an HTTP request and provide your Bearer Token with the "Authorization: Bearer {token}" header. A Bearer Token is a cryptic string typically generated by the server in response to a login request.
Click Send to run the GET request with a bearer token authorization header example online and see results. The Java code was automatically generated for the GET Request Bearer Token Authorization Header example. x Loading...
Authorization Bearer Header [Java Code] An example of sending an authorization bearer header with an API request. The authorization bearer header is sent to the server in Authorization: Bearer {token} request header. The bearer token is a cryptic string, usually returned by the server in the previous request.
In this post we will explain how to authenticate an API using tokens, which will help ensure that users who use our services have permissions to do so and are who they say they are. Create an API rest with Spring Boot. Protect resources published in the API. Implement a controller to authenticate users and generate an access token.
Yeah, the code that configures the handling of the bearer token. Token is a string value, therefore, you don't need to deserialize it again. This is simply a token string which can directly send with request for authentication.
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.
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With