Saltar al contenido

¿Cómo obtener el token de portador del encabezado de una solicitud en java spring boot?

Solución:

Aunque las respuestas sugeridas funcionan, pasar el token cada vez a FeignClient las llamadas aún no son la mejor manera de hacerlo. Sugeriría crear un interceptor para solicitudes fingidas y allí puede extraer el token de RequestContextHolder y agréguelo al encabezado de solicitud directamente. como esto:

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

de esta manera tienes una solución limpia para tu problema

Tienes varias opciones aquí.

Por ejemplo, puede utilizar un bean con ámbito de solicitud y, como sugiere, un interceptor MVC.

Básicamente, debe definir un contenedor para el valor del token:

public class BearerTokenWrapper {
   private String token;

   // setters and getters
}

Luego, proporcione una implementación de un 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;
  }
}

Este interceptor debe registrarse en su configuración MVC. Por ejemplo:

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

}

Con esta configuración, puede utilizar el bean en su Service Cableado automático del bean correspondiente:

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

Se han proporcionado soluciones similares aquí en el desbordamiento de pila. Vea, por ejemplo, esta pregunta relacionada.

Además de este enfoque basado en Spring, puede probar algo similar a la solución expuesta en esta otra pregunta de stackoverflow.

Honestamente, nunca lo he probado, pero parece que puede proporcionar el valor del encabezado de la solicitud directamente en la definición del cliente de Feign, en su caso, algo como:

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

Por supuesto, también puede Controller ese otro Controllers puede extenderse. Esta Controller proporcionará la lógica necesaria para obtener el token de portador del Authorization encabezado y la solicitud HTTP proporcionada, pero en mi opinión, cualquiera de las soluciones mencionadas es mejor.

Tuve un caso similar. Estaba interceptando las solicitudes de un microservicio, obteniendo el token y configurándolo en mi nuevo ApiClient y llamando al punto final desde otro microservicio usando este ApiClient. Pero realmente no sé si existe la posibilidad de preconfigurar el cliente fingido. Una cosa que puede hacer es crear DefaultApiFilter, interceptar la solicitud, guardar el token en su base de datos (o configurarlo en alguna variable estática, alguna clase singleton o algo similar) y luego llamar a su método de servicio cuando intente usar el FeignClient:

package com.north.config;

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@Component
public class DefaultApiFilter implements Filter {


@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) servletRequest;

    String auth = req.getHeader("Authorization");

    //TODO if you want you can persist your token here and use it on other place

    //TODO This may be used for verification if it comes from the right endpoint and if you should save the token
    final String requestURI = ((RequestFacade) servletRequest).getRequestURI();

    filterChain.doFilter(servletRequest, servletResponse);
    }
}

Esta doFilter El método siempre se ejecutará antes de que se llame a cualquier punto final, y luego se llamará al punto final.

Y luego úselo cuando llame al accountFeignClient.getData("Bearer " + tokenString, ids); puede obtenerlo de su base de datos (o de cualquier otro lugar donde lo guardó) y configurarlo aquí.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *