403当AWS WebSocket API Gateway尝试通过Cloudfront提供服务时禁止

yrwegjxp  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(159)

我使用AWS的WebSocket API网关创建了一个WebSocket API。在创建API之后,我得到了如下端点:
wss://x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com/dev
我可以直接使用它并调用$connect lambda,而不会有任何问题。
现在,我想通过CloudFront提供这个服务。
我已经有一个发行版,它有一个备用域名,如app.blablabla.cloud,它提供多个REST API(Origin Type:API Gateway)。我也想为WebSocket API做同样的事情
我为发行版创建了一个新的自定义源

  • 原始域-x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com
  • 协议-仅HTTPS
  • HTTPS端口- 443
  • 最低源SSL协议- TLS v1
  • 源路径- * 留空 *
  • 其余配置-默认

在那之后,我创建了一个行为,并附加了这个起源

  • 路径模式-/dev/my-socket/*
  • 自动压缩对象-是
  • 查看器-仅HTTPS
  • 允许的HTTP方法- GET、HEAD、OPTIONS、PUT、POST、PATCH、HTTP
  • 限制查看器访问-否
  • 缓存键和原始请求-缓存策略和原始请求策略
    缓存策略- CachingDisabled
    源请求策略-创建了Cookies - AllQuery strings - AllHeaders - Include the following headers - Sec-WebSocket-Key, Sec-WebSocket-Version, Sec-WebSocket-Protocol, Sec-WebSocket-Accept, Sec-WebSocket-Extensions策略
  • 其余配置-默认

现在,我尝试使用URL wss://app.blablabla.cloud/dev/my-socket/?param1=1&param2=test从postman调用wss初始调用
但是我得到了Status Code: 403 Forbidden(我期待一个101 Switching Protocols),而且请求头是

Sec-WebSocket-Version: 13
Sec-WebSocket-Key: TVMDG46dqkDM4a7DoM20ZB==
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: app.blablabla.cloud

所以看起来云锋被击中了无法通过API网关 Jmeter 板还显示了类似x1c 0d1x内容
我不明白问题出在哪里。非常感谢帮助。提前感谢!

wpcxdonn

wpcxdonn1#

编辑

后来尝试用cloudfront函数here,觉得是比较好的办法
问题是API Gateway’s WebSocket API does not support a path parameter in the connection URL. By design (or say it a design oversight), the connection URL path is fixed to the root path / (stage would be prepended when execute-api endpoint is used).,如在此medium article中提到的。
简单地说,尝试连接wss://x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com/dev/my-socket/?param1=1&param2=test将给予相同的403禁止。只有wss://x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com/dev/?param1=1&param2=testwss://x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com/dev?param1=1&param2=test可以工作。
即当我尝试连接wss://app.blablabla.cloud/dev/my-socket/?param1=1&param2=test时,它必须尝试连接到wss://x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com/dev/my-socket/?param1=1&param2=test
所以方法1

  • 在行为更改路径模式-**/dev**并降低优先级,以便dev/stuff/*的其余部分不受影响。
  • 现在我可以做wss://app.blablabla.cloud/dev?param1=1&param2=test

但这是不可扩展的。如果我们需要另一个套接字API。我们不能对所有东西都使用相同的/dev
这导致更好的方法2
使用Lambda@Edge

  • 保持Path模式-/dev/my-socket/*的行为。
  • 创建一个Lambda@Edge并关联Origin请求
  • lambda很简单,只是将uri/dev/my-socket/改为/dev
'use strict';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  request.uri = request.uri.replace(/\/[^\/]+\/$/, '');
  return callback(null, request);
};
  • 现在我能够做wss://app.blablabla.cloud/dev/my-socket/?param1=1&param2=test,它将剥离my-socket并转发到正确的原点。
  • 此外,Lambda仅在连接调用期间调用。握手完成后,Lambda不参与。
  • 还注意到,与直接使用API网关url相比,这种方法有轻微的延迟

相关问题