Linux无代理环境下Spring RestTemplate调用Lithium API报401未授权
我来帮你排查这个401未授权的问题,结合你描述的场景,给你几个在Linux无代理环境下的排查方向和解决办法:
排查与解决方案
1. 优先检查Base64编码的字符集与格式问题
你的代码中使用了默认字符集生成凭证字节数组,而Windows和Linux的默认字符集可能不一致(Windows通常是GBK,Linux多为UTF-8),Lithium API大概率要求UTF-8编码的凭证。另外,手动转字符串可能引入多余换行符,破坏Authorization头的有效性:
- 修改代码指定UTF-8字符集,并使用更可靠的Base64编码方法:
import java.nio.charset.StandardCharsets; import org.apache.commons.codec.binary.Base64; String plainCreds = lswUserName + ":" + lswPassword; byte[] plainCredsBytes = plainCreds.getBytes(StandardCharsets.UTF_8); // 直接用encodeBase64String避免手动转字符串的问题 String base64Creds = Base64.encodeBase64String(plainCredsBytes); HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Basic " + base64Creds);
2. 确认RestTemplate是否正确处理HTTPS证书
Postman默认信任多数证书,但Java的RestTemplate依赖系统信任库。如果Lithium的SSL证书不在Linux的Java信任库中,可能会导致请求被拦截,伪装成401错误:
- 临时排查方案:自定义忽略证书验证的RestTemplate(仅用于测试,生产环境禁用):
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContexts; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; @Bean public RestTemplate restTemplate() throws Exception { TrustStrategy trustAll = (chain, authType) -> true; SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(null, trustAll) .build(); SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext); CloseableHttpClient httpClient = HttpClients.custom() .setSSLSocketFactory(socketFactory) .build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); return new RestTemplate(factory); } - 生产环境解决方案:将Lithium的证书导入Linux系统的Java信任库:
# 默认信任库路径为$JAVA_HOME/jre/lib/security/cacerts,默认密码changeit keytool -import -alias lithium-cert -file /path/to/your/lithium.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
3. 补全请求头,对齐Postman的请求格式
Postman会自动添加Accept、Content-Type等标准头,而你的代码仅设置了Authorization头,部分API需要这些头才能正确处理授权:
import java.util.Collections; import org.springframework.http.MediaType; headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.setContentType(MediaType.APPLICATION_JSON);
4. 清理残留的代理配置
虽然你确认系统无代理,但可能存在残留的JVM参数或环境变量:
- 检查JVM启动参数:执行
ps aux | grep java,查看是否有-Dhttp.proxyHost类参数,若有则移除后重启应用。 - 检查系统环境变量:执行
echo $http_proxy、echo $https_proxy,若有值则执行unset http_proxy、unset https_proxy,再重启应用。
5. 开启日志调试,对比请求细节
开启RestTemplate的详细日志,查看实际发送的请求头与Postman的差异:
在application.properties中添加:
logging.level.org.springframework.web.client.RestTemplate=DEBUG logging.level.org.apache.http=DEBUG
通过日志可以确认Authorization头是否正确、请求是否被篡改,以及响应的具体错误信息。
内容的提问来源于stack exchange,提问作者user3278232
相关产品推荐
相关产品推荐

