如何从java spring boot中的请求标头获取承载令牌?

新手上路,请多包涵

嗨,试图实现的是在 java spring boot RESTApi 控制器中获取从前端提交的不记名令牌,并使用假客户端向另一个微服务发出另一个请求?这就是我所做的

在此处输入图像描述

上图是我如何处理邮递员的请求,这是我的控制器代码:

 @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);
}

这是我的服务的样子:

 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;
}

如您所见,在“tokenString”中我放了一个我质疑的字符串,我如何从邮递员那里得到它?

原文由 Ke Vin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 604
2 个回答

尽管建议的答案有效,但每次将令牌传递给 FeignClient 调用仍然不是最好的方法。我建议为假请求创建一个拦截器,您可以在那里从 RequestContextHolder 中提取令牌并将其直接添加到请求标头中。像这样:

     @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());

      }
    }

这样你就有了一个干净的解决方案来解决你的问题

原文由 stacker 发布,翻译遵循 CC BY-SA 4.0 许可协议

您在这里有多种选择。

例如,您可以使用一个 请求作用域的 bean ,正如您所建议的,一个 MVC 拦截器

基本上,您需要为令牌值定义一个包装器:

 public class BearerTokenWrapper {
   private String token;

   // setters and getters
}

然后,提供 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;
  }
}

此拦截器应在您的 MVC 配置中注册。例如:

 @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();
  }

}

使用此设置,您可以在 Service 中使用 bean 自动装配相应的 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;
}

堆栈溢出中提供了类似的解决方案。例如,请参阅 此相关问题

除了这种基于 Spring 的方法之外,您还可以尝试类似于 其他 stackoverflow 问题 中公开的解决方案的方法。

老实说我从来没有测试过它,但似乎你可以在 Feign 客户端定义中提供请求标头值,在你的情况下是这样的:

 @FeignClient(name="AccountFeignClient")
public interface AccountFeignClient {
    @RequestMapping(method = RequestMethod.GET, value = "/data")
    List<PartnerDto> getData(@RequestHeader("Authorization") String token, Set<Long> ids);
}

当然,您也可以使用其他 Controller 可以扩展的通用 Controller 。这个 Controller 将提供从 Authorization 标头和提供的 HTTP 请求获取承载令牌所需的逻辑,但在我看来,上述任何解决方案都更好。

原文由 jccampanero 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题