为啥缺少授权标头?

Posted

技术标签:

【中文标题】为啥缺少授权标头?【英文标题】: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。

为什么缺少授权标头?

【问题讨论】:

【参考方案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 就像一个代理,网关正在转发请求。你试过我的解决方案了吗? 我试过了,但它变得复杂了很多我不知道的事情。但我必须继续走得更远,所以我只是使用另一个令牌。无论如何,谢谢。

以上是关于为啥缺少授权标头?的主要内容,如果未能解决你的问题,请参考以下文章

使用 JWT 缺少授权标头

POST请求中缺少授权标头[重复]

如果通过 Zuul API 网关发送请求,则缺少授权标头

Flask Restful NoAuthorizationError 缺少授权标头

仅在生产中缺少授权标头

Django TokenAuthentication 缺少“授权”http 标头