You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)
  }
}

额外排查点(如果上述修复后仍有问题)

  1. 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)
    
  2. 版本升级:Akka-HTTP 10.1.0确实比较老旧,存在一些已知的SSL相关bug,如果可以的话,建议升级到10.2.x系列的稳定版本,兼容性和安全性都会更好。

内容的提问来源于stack exchange,提问作者Reeebuuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:59:08