Akka-HTTP发起HTTPS请求返回403错误求助
解决Akka-HTTP调用接口返回403 Forbidden的问题
首先得说,你的代码里有几个非常明显的问题,大概率是这些问题导致了403,先从最直接的点入手:
1. 请求体完全不匹配
你在curl里发送的是正确的JSON payload {"sophisInternalIds": [67108959]},但Akka-HTTP代码里写的是entity = "lala"——服务器收到这种完全不符合要求的请求体,直接返回403太正常了,这是最核心的问题。
2. 缺失必要的请求头
curl里明确设置了accept: application/json和content-type: application/json,但你的Akka请求里完全没加这些头。很多API会严格校验Content-Type来确保接收的是合法数据,缺少这些头也会触发服务器的拒绝逻辑。
3. SSL上下文的潜在配置问题
虽然你跳过了证书验证,但Akka-HTTP 10.1.0这个老版本(2018年发布)的SSL处理可能有一些细节需要注意,比如SNI(Server Name Indication)支持,有些服务器要求必须携带SNI才能正常响应。
修正后的完整代码
我把这些问题都修复了,你可以直接测试:
import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model._ import akka.util.ByteString import javax.net.ssl.{SSLContext, X509TrustManager} object FixedAkkaHttpRequest { def main(args: Array[String]): Unit = { implicit val system: ActorSystem = ActorSystem("StructuredProductsRequest") // 配置信任所有证书的SSL上下文(和你的逻辑一致,优化了空数组的写法) private val trustfulSslContext: SSLContext = { object NoCheckX509TrustManager extends X509TrustManager { override def checkClientTrusted(chain: Array[java.security.cert.X509Certificate], authType: String): Unit = () override def checkServerTrusted(chain: Array[java.security.cert.X509Certificate], authType: String): Unit = () override def getAcceptedIssuers: Array[java.security.cert.X509Certificate] = Array.empty } val context = SSLContext.getInstance("TLS") context.init(null, Array(NoCheckX509TrustManager), new java.security.SecureRandom()) context } // 1. 构造正确的JSON请求体 val requestBody = """{"sophisInternalIds": [67108959]}""" val jsonEntity = HttpEntity(ContentTypes.`application/json`, requestBody) // 2. 构造完整的请求,添加必要的请求头 val targetUrl = "https://structuredproducts-ch.leonteq.com/engine-api/feed/timeseries/request?from=201805310000&to=201805311602" val httpRequest = HttpRequest( uri = Uri(targetUrl), method = HttpMethods.POST, entity = jsonEntity, headers = List( headers.Accept(MediaTypes.`application/json`), // 模拟curl的User-Agent,部分服务器会拦截无UA的请求 headers.RawHeader("User-Agent", "curl/7.68.0") ), protocol = HttpProtocols.`HTTP/1.1` ) // 3. 发送请求并处理响应 Http(system).singleRequest(httpRequest, connectionContext = ConnectionContext.https(trustfulSslContext)) .onComplete { case scala.util.Success(response) => println(s"响应状态码: ${response.status}") // 读取响应体内容 response.entity.dataBytes.runFold(ByteString.empty)(_ ++ _).foreach { body => println(s"响应内容: ${body.utf8String}") } case scala.util.Failure(ex) => println(s"请求失败: ${ex.getMessage}") ex.printStackTrace() }(system.dispatcher) } }
额外排查点(如果上述修复后仍有问题)
- SNI配置:如果服务器要求SNI,你可以给客户端连接添加SSL参数配置:
import akka.http.scaladsl.settings.ClientConnectionSettings import javax.net.ssl.SSLParameters val sslParams = new SSLParameters() sslParams.setEndpointIdentificationAlgorithm("HTTPS") val connectionSettings = ClientConnectionSettings(system).withSslParameters(sslParams) // 发送请求时指定settings Http(system).singleRequest(httpRequest, connectionContext = ConnectionContext.https(trustfulSslContext), settings = connectionSettings) - 版本升级:Akka-HTTP 10.1.0确实比较老旧,存在一些已知的SSL相关bug,如果可以的话,建议升级到10.2.x系列的稳定版本,兼容性和安全性都会更好。
内容的提问来源于stack exchange,提问作者Reeebuuk
相关产品推荐
相关产品推荐

