【问题标题】:Why is Authorization Header missing?为什么缺少授权标头?
【发布时间】:2019-04-20 10:14:53
【问题描述】:

我有 Eureka 和连接的服务 Zuul:8090AuthService:[any_port]

我向 Zuul 发送 ../login 请求,他发送给 AuthSercice。然后 AuthSerice 放入 Header JWT Authentication。

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
    String token = Jwts.builder()
            .setSubject( ((User) authResult.getPrincipal()).getUsername())
            .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
            .signWith(SignatureAlgorithm.HS512, SECRET)
            .compact();

    response.addHeader("Authorization", "Bearer "+ token); // this is missing
    response.addHeader("Authorization2", "Bearer " + token); // ok
}

我确实要求邮递员。 Request result

首先我尝试在 Monoliths 中使用 JWT。没有问题,可以添加Authorization Token。

为什么缺少授权标头?

【问题讨论】:

    标签: java authentication jwt microservices


    【解决方案1】:

    这是因为 Zuul 内置的机制——它会自动过滤掉敏感的标头,例如 AuthorizationCookies,以保护敏感信息不被转发到下游服务。 这就是为什么您无法获取名称为Authorization 的标头。

    如果您希望您的下游服务接收它们,只需在您的 Zuul 配置文件中自己定义过滤器,而不是使用默认值。

     zuul:
      routes:
        users:
          path: your url pattern
          sensitiveHeaders: //put nothing here!! leave it blank, the filter will be off
          url: downstream url
    

    这里是spring官方对敏感头的解释:document

    【讨论】:

      【解决方案2】:

      您需要在 Eureka 中设置转发标头的选项。 对于登录,我建议使用自定义 ZuulFilter。

      public abstract class AuthenticationZuulFilter extends ZuulFilter {
      
      private static final Log logger = getLog(AuthenticationZuulFilter.class);
      
      private static final String BEARER_TOKEN_TYPE = "Bearer ";
      private static final String PRE_ZUUL_FILTER_TYPE = "pre";
      
      private AuthTokenProvider tokenProvider;
      
      public AuthenticationZuulFilter(AuthTokenProvider tokenProvider) {
          this.tokenProvider = tokenProvider;
      }
      
      @Override
      public Object run() {
          RequestContext ctx = getCurrentContext();
          ctx.addZuulRequestHeader(X_USER_INFO_HEADER_NAME, buildUserInfoHeaderFromAuthentication());
          ctx.addZuulRequestHeader(AUTHORIZATION, BEARER_TOKEN_TYPE + tokenProvider.getToken());
          return null;
      }
      
      @Override
      public String filterType() {
          return PRE_ZUUL_FILTER_TYPE;
      }
      
      @Override
      public int filterOrder() {
          return 1;
      }
      

      这是一个实现,它可以是这样的。

      @Component
      public class UserAuthenticationZuulFilter extends AuthenticationZuulFilter {
      
      @Value("#{'${user.allowed.paths}'.split(',')}")
      private List<String> allowedPathAntPatterns;
      
      private PathMatcher pathMatcher = new AntPathMatcher();
      
      @Autowired
      public UserAuthenticationZuulFilter (AuthTokenProvider tokenProvider) {
          super(tokenProvider);
      }
      
      @Override
      public boolean shouldFilter() {
          Authentication auth = getContext().getAuthentication();
          HttpServletRequest request = getCurrentContext().getRequest();
          String requestUri = request.getRequestURI();
          String requestMethod = request.getMethod();
          return auth instanceof UserAuthenticationZuulFilter && GET.matches(requestMethod) && isAllowedPath(requestUri);
      }
      

      }

      【讨论】:

      • 感谢您的回复。但我不明白为什么... 1. 为什么我需要 Eureka 中的前向标头? 2. 其实我可以使用Another_Auth_Header。我不明白为什么要删除身份验证标头。
      • Zuul 就像一个代理,网关正在转发请求。你试过我的解决方案了吗?
      • 我试过了,但它变得复杂了很多我不知道的事情。但我必须继续走得更远,所以我只是使用另一个令牌。无论如何,谢谢。
      猜你喜欢
      • 2012-10-27
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 2023-02-01
      • 2019-06-17
      • 1970-01-01
      • 2017-03-21
      相关资源
      最近更新 更多