应用程序防火墙提供对分布式系统中客户端连接的复杂控制。 在深入了解其功能和设置之前,让我们阐明应用程序防火墙不执行的操作:
- 它不会替换身份验证。 防火墙在客户端连接身份验证层后面运行。
- 它与网络层访问控制无关。
应用程序防火墙由各种规则列表组成。 目前,有一个名为“客户端连接计数规则”的规则列表。 未来的更新将支持更多规则列表,用于控制连接生存期和消息吞吐量等方面。
此准则分为三个部分:
- 不同应用程序防火墙规则简介。
- 有关使用门户或 Bicep 在 SignalR 服务端配置规则的说明。
- 在服务器端配置令牌的步骤。
- 高级层中的 Azure SignalR 服务。
客户端连接计数规则限制并发客户端连接。 当客户端尝试建立新连接时,会按顺序检查规则。 如果违反任何规则,则连接将被拒绝,状态代码为 429。
此规则限制用户的并发连接数。 例如,如果用户使用不同的设备打开多个浏览器选项卡或登录,则可以使用此规则来限制该用户的并发连接数。
注意
- UserId 必须存在于访问令牌中,此规则才有效。 请参阅配置访问令牌。
此规则限制同一令牌的并发连接数,以防止恶意用户重用令牌来建立无限连接,这可能会耗尽连接配额。
注意
- 默认情况下,不能保证 SDK 生成的令牌每次都不同。 尽管每个令牌都包含时间戳,但如果在数秒内生成大量令牌,则此时间戳可能相同。 若要避免相同的令牌,请将随机声明插入令牌声明。 请参阅配置访问令牌。
更高级,可以根据自定义声明将连接分组到不同的组中。 系统将对具有相同声明的连接进行汇总,以执行该检查。 例如,可以添加 ThrottleByJwtCustomClaimRule,以允许具有 5 个使用自定义声明名称“freeUser”的并发连接。
注意
- 该规则适用于具有特定声明名称的所有声明。 连接计数汇总是基于同一声明(包括声明名称和声明值)。 ThrottleByUserIdRule 是此规则的一种特殊情况,适用于采用 userIdentity 声明的所有连接。
警告
- 避免使用过于激进的 maxCount。 客户端连接可能会在不完成 TCP 握手的情况下关闭。 SignalR 服务无法立即检测到这些“半关闭”连接。 连接被视为活动,直到检测信号失败。 因此,激进的限制策略可能会意外地限制客户端。 更流畅的方法是为连接计数保留一些缓冲区,例如:将 maxCount 加倍。
仅当访问令牌包含相应的声明时,应用程序防火墙规则才会生效。 如果连接没有相应的声明,则跳过规则。
下面是一个在默认模式下在访问令牌中添加 userId 或自定义声明的示例:
services.AddSignalR().AddAzureSignalR(options =>
{
// Add necessary claims according to your rules.
options.ClaimsProvider = context => new[]
{
// Add UserId: Used in ThrottleByUserIdRule
new Claim(ClaimTypes.NameIdentifier, context.Request.Query["username"]),
// Add unique claim: Ensure uniqueness when using ThrottleByJwtSignatureRule.
// The token name is not important. You could change it as you like.
new Claim("uniqueToken", Guid.NewGuid().ToString()),
// Custom claim: Used in ThrottleByJwtCustomClaimRule
new Claim("<Custom Claim Name>", "<Custom Claim Value>"),
// Custom claim example
new Claim("freeUser", context.Request.Query["username"]),
};
});
无服务器模式的逻辑与此类似。
有关详细信息,请参阅客户端协商。