Skip to content

MindSphere 网关

简介

MindSphere 网关可作为 MindSphere 云后端的网关,用于 Web 应用客户端、代理和边缘应用,以及所有外部和内部应用后端与服务。 用户可以使用外部网关从 Internet 访问与 MindSphere 网关集成的 Web 应用或 Web 服务。路由必须由使用 Gateway Registry 的每个应用或服务提供者定义。 身份管理与网关集成,以支持 Web 应用 OAuth 2.0 授权代码流,并在跨提供者请求中交换交互式或活动客户端的访问令牌。

gateway

RFC 合规性

标准

MindSphere Gateway符合以下标准,并希望每个通过MindSphere Gateway与MindSphere进行交互的客户端都遵守这些标准。

注意

MindSphere Gateway不支持任何违反这些标准的行为。
如果在MindSphere网关中发现任何违反标准的行为,则将在不进一步通知的情况下立即对其进行修复,以利于系统的可用性,稳定性和可靠性。

典型违反标准的示例

以下URL有一个常见错误:

不符合RFC的URL:

https://example-application.eu1.mindsphere.io/getDataByIds?idList=[1,2,3,4,5,6]

符合RFC的URL:

https://example-application.eu1.mindsphere.io/getDataByIds?idList=%5B1,2,3,4,5,6%5D

说明: 根据RFC-3986, 字符 [ and ] 属于 gen-delims 集合, URL的查询字符串部分中不允许使用这些字符。 但是,查询字符串可能包含属于 pchar 集合的字符, 包括 sub-delims 集合。由于逗号字符是此集合的一部分,因此不需要进行编码。
对逗号字符进行百分比编码也将在标准范围内。

在URL中使用保留字符

URL的每个部分都有其自己的架构,带有不同的保留字符集。 开发人员在对MindSphere中使用的URL进行编码或解码时需要考虑到这一点。 有关更多信息,请阅读RFC-3986的第2章和第3章。

URL 方案

下文定义了映射到 MindSphere 网关的公共 URL 的 URL 方案。公共 URL 可从 Internet 调用。MindSphere 网关将对公共 URL 的请求路由到已注册的内部 IP,比如您的内部 Cloud Foundry 应用路由。

大括号 {} 用于定义强制 URL 部分的占位符,方括号 [] 用于定义仅在定义的特定情况下所需的占位符。

调用 MindSphere Web 应用

MindSphere 中托管的 Web 应用可以在以下主机名下的网关处提供:

{tenantName}-{webApp}[-{provider}].{region}[-{env}].{mindsphere-domain}/[{path}]

描述

  • {tenantName} 表示访问 Web 应用的租户。它有助于将用户定向到该租户可用的 IdP,同时允许在浏览器中创建特定于租户的书签。
  • {webapp}[-{provider}] 对 Web 应用进行了唯一标识。MindSphere 核心 Web 应用省略了提供者部分,而其它 Web 应用需要包含此部分以避免名称冲突,并保持核心命名空间的整洁。
  • {region}[-{env}] 表示请求发送的数据中心区域env 部分用于标识环境(例如 preview),仅附加在预览环境中。
  • {mindsphere-domain} 表示请求发送的数据中心域
  • [{path}] 为可选路径参数,用于访问 Web 应用的子内容。第一个路径参数不能与 /api 相同,以避免与 API 路由冲突。
示例
  • abc-fleetmanager.eu1.mindsphere.io:租户 abc 的用户从区域Europe 1(生产环境)中的 Fleet Manager Web 应用加载内容。
  • abc-fleetmanager-xyz.eu2.mindsphere.io/index.html:租户 abc 的用户从区域Europe 2(生产环境)中的提供者 xyz 的 Fleet Manager Web 应用加载索引页。
  • xyz-fancyfleetmanager-xyz.cn1.mindsphere-in.cn/images/icon.jpg:租户 xyz 的用户从区域China 1(生产环境)中的提供者 xyz 的 Fleet Manager Web 应用加载图标。

Web 应用客户端调用 MindSphere API

Web 应用客户端在用于检索该客户端的相同主机名下调用 MindSphere API。URL 路径参数确定了调用目标。

{webAppHost}/api/{apiName}[-{apiProvider}]/v{major}/{endpoint}

描述

  • {webAppHost} 请参见调用 MindSphere Web 应用小节。
  • {apiName}[-{apiProvider}] 对 API 进行了唯一标识。核心 API 省略了 apiProvider 部分以简化 URL。非核心 API 需要附加 API 的提供者名称,以避免名称冲突并保持核心命名空间的整洁。
  • v {major} 表示 API 的主要版本。
  • {endpoint} 表示 API 的端点,可以使用嵌套路径。
示例
  • abc-fleetmanager.eu2.mindsphere.io/api/iot/v2/assets:租户 abc 的用户使用区域Europe 2 中的 Fleet Manager Web 应用客户端访问 IoT 核心 API v2(端点 assets)。
  • abc-fleetmanager.eu1.mindsphere.io/services/fleetmanager/v3/fleets:租户 abc 的用户使用区域Europe 1中的 Fleet Manager Web 应用客户端访问 fleetmanager UI mashup(核心)API v3(端点 fleets)。
  • abc-fleetmanager-xyz.eu2.mindsphere.io/services/iot-xyz/v3/assets/46b55e6f:租户 abc 的用户使用区域Europe 2中的 Fleet Manager Web 应用客户端访问 xyz IoT 服务 v3(端点 assets/46b55e6f)。

活动客户端调用 MindSphere API

活动客户端应该在 Web 浏览器之外运行。它们不需要主机名中的租户或 Web 应用标识符。但是,确定目标 API 的方法与调用 Web 应用客户端的方法相同。

gateway.{region}[-{env}].{mindsphere-domain}/api/{apiName}[-{apiProvider}]/v{major}/{endpoint}

描述

示例
  • gateway.region123.mindsphere.io/api/iot/v3/assets:客户端调用区域 region123 访问 IoT 核心 API v3(端点 assets)。
  • gateway.region123.mindsphere.io/api/assetmanagement/v3/assets:客户端调用区域 region123 访问 Asset 管理 API v3(端点 assets)。

设备代理调用 MindSphere 代理或边缘 API

设备代理以与通用北向客户端相同的方式调用 MindSphere,但使用不同的子域名。

southgate.{region}[-{env}].{mindsphere-domain}/api/{apiName}[-{apiProvider}]/v{major}/{endpoint}

描述

示例
  • southgate.eu1.mindsphere.io/api/service/v3/serviceEndpoint:代理调用区域Europe 1(生产环境)访问服务 API v3(端点 serviceEndpoint)。

URL 模式

MindSphere 网关支持 Ant 风格的路径模式匹配。

路径模式匹配和支持的通配符

用户可以使用通配符 ?*** 注册其 API 端点路径。

字符 描述
? 完全匹配某个字符
* 匹配零个或多个字符
** 匹配路径中的零个或多个目录
示例
  • /? 模式匹配 "/e""/b" 路径,但不匹配 "/endpoint" 等路径。
  • /en?po?nt 模式匹配 "endpoint""enbpoent" 等路径。
  • /?ndpoint 模式匹配 "endpoint""andpoint" 等路径。

  • /* 模式匹配 """/""/endpoint""/epoint" 等路径。

  • /*/endpoint 模式匹配 "/api/endpoint""//endpoint" 路径,但不匹配"/api//endpoint""/api/andpont"等路径。
  • public/*.jsp 模式匹配公共目录中的所有 ".jsp files"

  • /** 模式基本匹配所有路径,而不仅仅是以下示例中的 """/""/endpoint""/public/endpoint""///endpoint" 等路径。

  • /**/endpoint 模式匹配 "/endpoint""//endpoint""/public/endpoint""/public/directory/in/path/endpoint" 路径,但不匹配 "/public/directory/noendpoint" 等路径。
  • /**/endpoint/** 模式匹配 "/endpoint""/endpoint/directory""/public/endpoint/directory/in/path" 路径,但不匹配 "/public/directory/noendpoint" 等路径。

  • /*/end?oint/** 模式匹配 "/directory/endpoint/directories/in/path""//endpoint/" 路径,但不匹配 "/directories/in/path/andpoint/directories/in/path" 等路径。

限制

当用户向自己注册的应用或 MindSphere API 发出请求时,将强制执行以下限制。这些限制仅适用于 MindSphere 网关,单独用于 MindSphere API 端点的限制可能更加严格。

选项 描述
Connection idle timeout 60 秒 将请求转发到后端服务的超时时间。如果在这段时间内没有数据流量,则“MindSphere 网关”(和/或 ALB)将关闭连接。理论上,服务可以通过每分钟发送至少 1 个字节来无限期地保持 WebSocket 连接。
Parallel connection count 400 每个 MindSphere 网关实例的最大并发连接数。
Cache invalidation timeout 12 小时 MindSphere 网关内部缓存超时时间(从 Gateway Registry 等依赖服务加载的数据无效)。
Session timeout 12 小时 用户会话的最大生命周期。用户必须在超时后重新登录。
Session inactive timeout 30 分钟 没有用户活动的会话的最大生命周期。
Session cookie timeout 无限时 会话 cookie 的最大生命周期。
Access token expiration 30 分钟 访问令牌的到期时间。
Refresh token expiration 12 小时 刷新令牌的到期时间。
Maximum request size 150 MB 可以发送的请求的最大大小。
Maximum file size 100 MB 可以附加到分块请求的文件的最大大小。
Maximum header size 16 kB 请求中消息头的最大大小。

连接空闲超时

MindSphere 网关限制了 HTTP 和 WebSocket 连接的空闲超时时间。

通过每分钟至少发送一个字节来保持连接。否则,MindSphere 网关将关闭连接,而客户端需要重新发送请求或重新连接到 WebSocket。

gateway

大型请求限制

如果超过了请求或文件的最大大小,通常在上传文件时,MindSphere 网关会返回带有 HTTP 状态 413 Payload Too Large 的错误响应,然后立即关闭连接。客户端应始终监控网络连接情况以获取错误响应,因为在连接关闭后,客户端将无法读取此类响应。

示例
场景 Content-Type HTTP 状态 消息
1 个小于 100 MB 的文件请求 分片/表单数据 200 OK {服务特定消息}
1 个大于 100 MB 的文件请求 分片/表单数据 413 Payload Too Large 超出请求内容长度限制
2 个文件请求,每个文件小于 100 MB,总计小于 150 MB 分片/表单数据 200 OK {服务特定消息}
2 个文件请求,每个文件小于 100 MB,总计超过 150 MB 分片/表单数据 413 Payload Too Large 超出请求内容长度限制
请求小于 150 MB 非分片/表单数据 200 OK {服务特定消息}
请求大于 150 MB 任意类型 413 Payload Too Large 超出请求内容长度限制

暂时阻止响应缓慢的端点

当向端点发送请求的速度超过响应的速度时,挂起的请求可能会使MindSphere Gateway实例负载过重。 通过将端点加入灰名单来防止这种情况。如果实例的负载超限,则会暂时阻止对响应缓慢的端点的访问。

当端点加入灰名单后,请求会收到HTTP状态为“503Backend service too slow”的响应。 目前,当端点响应时间超过30秒时,会被认为是响应缓慢的,灰名单会持续5分钟。 在此期间,只有当并发连接数低于80%,才会将请求转发到端点。

信息

目前,对于响应缓慢的端点,只是上报而非阻止。

网关错误内容类型

网关错误响应以 XML 或 JSON 格式发送。如果请求需要收到错误响应,则必须接受这些媒介类型。否则,如果发生错误,MindSphere 网关将发送 HTTP 状态 406 Not acceptable
消息头示例:

Accept:application/json, application/xml

安全性

授权

尽管 MindSphere 网关采用安全措施来保护 MindSphere 后端中的 Web 应用和服务,但每个 Web 应用和服务都需要应用授权审核以确保实现访问控制。

Cross-Site-Request-Forgery

MindSphere 网关要求 Web 应用使用提供的 CSRF 令牌机制,包括基于源 http 消息头的同源检查。

Content-Security-Policies (CSP)

MindSphere 网关对 Web 应用使用了严格的内容安全策略消息头,该消息头不能为第三方配置。所有提供的资源必须来自应用 uri 或静态内容 uri (static.{region}[-{env}].{mindsphere-domain})

Web 应用可以通过在响应中包含以下任一 HTTP 消息头来使用 CSP:

  • Content-Security-Policy
  • Content-Security-Policy-Report-Only

默认情况下,MindSphere 网关为 Web 应用添加 CSP 消息头:

Content-Security-Policy:default-src 'self' static.{region}.{mindsphere-domain}; style-src * 'unsafe-inline'; script-src 'self' 'unsafe-inline' static.{region}.{mindsphere-domain}; img-src * data:;

parties. 有关 CSP 的更多信息,请参见 W3C 的官方规范MDN Web 文档中的 CSP 文档

缓存控制

MindSphere 网关可以为请求和响应中的缓存机制使用 Web 应用的特定 Cache-Control 消息头值。配置值为缓存控制指令列表,其中包含符合缓存控制消息头规范的缓存配置规则。

  • 如果HTTP响应中提供了消息头Cache-Control, MindSphere网关会将它转发给客户端应用程序。
  • 如果HTTP响应中消息头Cache-Control为空或未提供,MindSphere网关会在上传应用的时候添加已配置的Cache-Control头部。
  • 如果在应用上传过程中消息头Cache-Control为空, 以下默认值会被添加到响应中:
Cache-Control:no-cache, no-store, max-age=0, must-revalidate

如果客户端应用程序使用HTTP/1.0协议,且响应中包含值为no-cacheCache-Control消息头,MindSphere网关会将Pragma: no-cache and Expires: 0消息头添加到响应中。对于HTTP/1.1及以上的协议,这些消息头都被省略了。

AJAX 请求

如果没有有效会话,则非 AJAX HTTP 请求将重定向到登录页面。
如果没有有效会话,消息头为 X-Requested-With: XMLHttpRequest 的 AJAX HTTP 请求将收到 HTTP 状态 401 Unauthorized

WebSockets

WebSocket 通信协议允许通过 TCP 连接进行全双工通信。MindSphere 网关支持在 Web 客户端和 Web 应用服务器之间建立 WebSocket 连接。为启用 WebSockets,Web 客户端和后端服务器必须能够使用安全的 wss 方案建立和驱动 WebSocket 连接。MindSphere 网关充当 WebSocket 连接的代理服务器,类似于 HTTP 请求。

配置 WebSocket 连接的应用

要配置 WebSockets,应用需要在 MindSphere 网关上注册端点,该端点允许 HTTP GET 请求并且能够使用 WebSocket。当 Web 客户端向此端点发送 WebSocket 升级请求时,将建立WebSocket 连接。

注意

目前,不支持通过Southgate进行WebSocket访问。

示例:带有内部 URL myApp.apps.eu1.mindsphere.io 的应用 myApp 在路径 / videostream 下有一个能够使用 WebSocket 的端点。该应用由操作员租户 myOperator 提供,并在 MindSphere 网关上作为 myTenant-myApp-myOperator.eu1.mindsphere.io 提供给租户 myTenant。myApp 的 Web 客户端可以通过 wss://myTenant-myApp-myOperator.eu1.mindsphere.io/videostream 与其后端建立 WebSocket 连接,该连接将被转发到 wss://myApp.apps.eu1.mindsphere.io/videostream

身份验证和授权

WebSocket 连接的身份验证和授权基于与 HTTP 请求相同的机制。Web 会话在客户端和 MindSphere 网关之间使用,而 Bearer 访问令牌用于内部转发的请求。但是,在建立 WebSocket 连接之后,由于 WebSocket 消息没有消息头部分,因此 Web 客户端和服务器之间的通信中将不再附加 HTTP 会话和访问令牌。

如果 HTTP 会话过期或 Web 客户端的用户注销,则会话以及随后的 WebSocket 连接都将关闭。
如果 WebSocket 连接上有流量,则 MindSphere 网关将在内部保持 HTTP 会话。

支持的 WebSocket 协议

MindSphere 网关不限制在 WebSockets 上使用的协议。这允许两个应用程序(使用WebSocket通过MindSphere Gateway进行通信)因此应用能够自由选择“语言”,但前提是MindSphere 网关和应用必须支持相同的协议。MindSphere 网关将每个 WebSocket 消息以二进制转发,不会干扰所使用的协议。例如, 可用协议包括:STOMP、Socket.IO、MQTT 或自定义协议 *

WebSocket 连接详细信息

消息头

WebSocket 连接以常规 HTTP 请求开始,即所谓的升级请求。Web 客户端和服务器必须协商需要使用的版本和扩展。协商成功后,服务器返回 HTTP 101 状态代码,并且 TCP 套接字保持打开状态以进行 WebSocket 通信。
下表包含升级请求的常用消息头。消息头的名称和值不区分大小写。 对于可选消息头,不允许使用空字符串作为值。 在这种情况下,消息头名称必须不存在。

消息头名称 消息头值 需要
Cookie: SESSION=<session-id>; REGION-SESSION=<region-session-id> yes
Connection: Upgrade yes
Upgrade: WebSocket yes
Sec-WebSocket-Version: 13* yes
Sec-WebSocket-Key: <generated websocket key> yes
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits * no
Sec-WebSocket-Protocol: <comma separated list> * ** no

通信流

  1. Web客户端对在MindSphere网关上注册的应用的端点执行WebSocket协议升级HTTP请求。
  2. MindSphere网关评估会话消息头和被调用的应用端点。
  3. MindSphere网关创建与目标端点的WebSocket web客户端连接。
  4. MindSphere网关向注册的应用程序后台发起新的WebSocket协议升级的HTTP请求。
  5. MindSphere网关对WebSocket升级返回状态码为101且携带必要头部的HTTP响应。
  6. 如果请求成功,客户端和后端能够通过代理的WebSocket双向发送消息。
  7. 如果 MindSphere网关与应用后端的连接失败,MindSphere网关将关闭HTTP与Web客户端的连接,并返回状态400 Bad Request。
WebSocket 通信示例

以下序列图中显示了使用 MindSphere 网关作为代理服务器时,Web 客户端(浏览器)与其后端之间的通信示例。

gateway

自动缩放和部署的影响

部署新版本的MindSphere Gateway时,在蓝/绿切换之后,Websocket连接将终止。 同样,自动缩放将关闭可能打开websocket连接的实例。

用户应用程序应该期望可以随时断开websocket连接,在这种情况下,他们应该尝试重新连接。

Ping/Pong 消息

目前, 没有浏览器公开用于JavaScript的ping / pong消息API。这意味着浏览器中的应用程序无法每分钟发送一次低级ping消息。使用STOMP或Socket.IO等其他协议,您可以通过发送高级ping消息来解决此问题。另一种解决方案是服务器需要向浏览器发送定期的ping消息,并且所有现代浏览器都会以pong消息进行响应。

WebSocket JavaScript使用示例

'use strict';
function connectWebsocket (url, protocols) {
  var socket;
  if (typeof protocols !== 'undefined' && protocols.length > 0) {
    // the array is defined and has at least one element
    socket = new WebSocket(url, protocols);
  } else {
    socket = new WebSocket(url);
    /*  
    *  The second parameter must be completly omitted in this case.
    *  If it is present, then an empty Sec-WebSocket-Protocol header will be added in most browsers,
    *  which will result in a connection error.
    *  The following code examples will produce an error:
    *  socket = new WebSocket(url , []);
    *  socket = new WebSocket(url , "");
    *  socket = new WebSocket(url , null);
    */
  }
  return socket;
}
// Example: using this function with ocpp subprotocol
var wsUrl = 'wss://tenant-application.eu1.mindsphere.io/websocket/example';
var subProtocols = [ 'ocpp2.0', 'ocpp1.6', 'ocpp1.5', 'ocpp1.2' ];
var webSocket = connectWebsocket(wsUrl, subProtocols);

websocket URL和返回的WebSocket对象格式记录在
HTML - Living Standard - Web sockets.

根据 RFC 6455, section 4.2.1, 应根据客户的喜好从最推荐的协议版本到最不推荐的协议版本对子协议列表进行排序。典型的实现通常从列表中选择他们可以理解的第一个。


Last update: March 22, 2023