zoukankan      html  css  js  c++  java
  • 自定义Feign拦截器,解决微服务之间Feign调用请求头丢失问题

    在微服务开发过程中,安全方面使用的是Spring Security OAuth2.0令牌认证,在进行服务与服务之间调用时,使用的Feign客户端,如果不通过Feign拦截器来添加请求头信息。下游服务是接收不到认证过的token令牌,无法进行身份验证。

    1. 定义Feign拦截器,实现 RequestInterceptor 接口

      @Slf4j
      public class FeignRequestInterceptor implements RequestInterceptor {
          /**
           * 微服务之间传递的唯一标识
           */
          public static final String X_REQUEST_ID = "X-Request-Id";
      
          @Override
          public void apply(RequestTemplate template) {
      
              HttpServletRequest httpServletRequest = getHttpServletRequest();
      
              if (httpServletRequest != null) {
                  //获取头信息
                  Map<String, String> headers = getHeaders(httpServletRequest);
                  // 传递所有请求头,防止部分丢失
                  Iterator<Map.Entry<String, String>> iterator = headers.entrySet().iterator();
      
                  //将请求的头信息放入到RequestTemplate 的头信息中,当使用RequestTemplate发起请求时会自动添加头信息
                  while (iterator.hasNext()) {
                      Map.Entry<String, String> entry = iterator.next();
                      template.header(entry.getKey(), entry.getValue());
                  }
                  // 微服务之间传递的唯一标识,区分大小写所以通过httpServletRequest获取
                  if (httpServletRequest.getHeader(X_REQUEST_ID) == null) {
                      String sid = String.valueOf(UUID.randomUUID());
                      template.header(X_REQUEST_ID, sid);
                  }
                  log.debug("FeignRequestInterceptor:{}", template.toString());
              }
          }
      
          /**
           * RequestContextHolder 中获取 HttpServletRequest对象
           *
           * @return
           */
          private HttpServletRequest getHttpServletRequest() {
              try {
                  return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
              } catch (Exception e) {
                  return null;
              }
          }
      
          /**
           * 获取头信息
           *
           * @param request
           * @return
           */
          private Map<String, String> getHeaders(HttpServletRequest request) {
              Map<String, String> map = new LinkedHashMap<>();
              Enumeration<String> enumeration = request.getHeaderNames();
              if (enumeration != null) {
                  while (enumeration.hasMoreElements()) {
                      String key = enumeration.nextElement();
                      String value = request.getHeader(key);
                      map.put(key, value);
                  }
              }
              return map;
          }
      
      }
      
    2. 配置Bean

      @Bean
          @ConditionalOnMissingBean(FeignRequestInterceptor.class)
          public RequestInterceptor feignRequestInterceptor() {
      
              FeignRequestInterceptor interceptor = new FeignRequestInterceptor();
              log.info("FeignRequestInterceptor [{}]", interceptor);
              return interceptor;
          }
      

      在每次进行调用时,会经过 OAuth2AuthenticationProcessingFilter 过滤器的 doFilter方法进行token验证,通过 tokenExtract 的 extract 方法抽取携带在请求中的令牌信息。

    3. OAuth2AuthenticationProcessingFilter 的 doFilter
      在这里插入图片描述

      如果认证成功,放入SpringContext上下文中

      在这里插入图片描述

    充满鲜花的世界到底在哪里
  • 相关阅读:
    FFmpeg之cmdutils.h源码
    iOS文件操作一览
    ffmpeg结构体SpecifierOpt说明文档
    主要流媒体协议介绍
    HTTP Live Streaming直播(iOS直播)技术分析与实现(转)
    XCode快捷键总结
    ALAssetsLibrary获取相册列表
    iOS教程之ASIHttpRequest(源自51CTO.com)
    libxml/tree.h not found(XCode 4.5&5.1解决方案)
    MyBatis——Log4J(日志)
  • 原文地址:https://www.cnblogs.com/aliases/p/14693292.html
Copyright © 2011-2022 走看看