【发布时间】:2020-03-13 01:21:36
【问题描述】:
在我的一项 REST 服务中,我使用 Spring Security 来验证在标头中传递的令牌。但是,即使存在“授权”标头,spring 也无法找到它。在测试中甚至在本地进行测试时,这不是问题,但是当我们部署到 PROD 时,我们遇到了这个问题。
作为替代/解决方法,我删除了 Spring 安全性,而是尝试在实际端点中验证我的令牌,然后继续执行其余请求,如下所示:
@PostMapping(value="/create",consumes="application/json; charset=utf-8")
@CrossOrigin
public ResponseEntity createAccount(@RequestBody MerchantAccount merchantAccount,@RequestHeader(name="Authorization") String token) {
log.info("Checking User Token");
if(!jwtUtil.isAuthorizedToken(token))
return ResponseEntity.status(401).build();
//some creating Account Logic
}
如果我再次执行上述操作,它将在 TEST 和 LOCAL 中有效,但在 PROD 中无效。我会回来的错误是“缺少授权标头”。但它又一次出现了。 (从邮递员测试到)。
经过一番研究,我发现我可以添加“,required=false”,这样spring就不会检查它,但是仍然没有要提取的令牌。
PROD 和 TEST 和我本地的唯一区别如下:
Java 版本
java版本测试中:java version "1.6.0_32"
PROD 上的 java 版本:java version "1.8.0_121"
本地java版本:java version "1.8.0_221"
在测试中,我们使用 HTTP 和 PROD,它是 HTTPS。 POM 文件中的 Spring Security 版本为 5.2
编辑 在我的网络配置中,我确实有一个部分允许显示“授权”标题,如下所示。
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("*"));//YOLO Allow all origins, we can change this once we go to prod
configuration.setAllowedMethods(ImmutableList.of("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH","OPTIONS"));//Allowed Methods
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type","Access-Control-Request-Headers","Access-Control-Request-Method",
"Accept","Access-Control-Allow-Headers"));//Allowed Headers
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
更新 在 TEST & LOCAL 上,当我遍历请求过滤器中的标头时(如下所示)
@Component
@Service
public class JwtRequestFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
logger.info("Done Getting Headers");
Collections.list(request.getHeaderNames()).forEach(item -> logger.info("header name is " + item));
logger.info("Done Getting Headers");
boolean isAccessToken = true;
final String requestTokenHeader = request.getHeader("authorization");//This is null as the Authorization header is not found in request
}
我得到以下输出。 测试和本地
在 PROD 上,我得到以下信息:
请帮忙。
【问题讨论】:
-
标头有实际值吗?可能是空的。如果您在代理/防火墙/负载平衡器/...后面运行。可能是标头已经被阻塞在那里,并且下游服务不再可以访问它(至少这是看起来的样子)。我建议看一下更大的图景(包括基础设施)并绘制差异图。我怀疑你会发现那里有东西阻塞/过滤它。并删除解决方法,如果 Spring Security 无法通过
request.getHeader获得它,您也不能。 -
您是否检查了您的 nginx / 代理配置文件是否有可能过滤掉标头的内容?
标签: java spring rest spring-boot spring-security