Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The Application Firewall provides sophisticated control over client connections in a distributed system. Before diving into its functionality and setup, let's clarify what the Application Firewall does not do:
- It does not replace authentication. The firewall operates behind the client connection authentication layer.
- It is not related to network layer access control.
The Application Firewall consists of various rule lists. Currently, there are two rule lists called Client Connection Count Rules and Client Traffic Control Rules. Future updates will support more rule lists to control aspects such as connection lifetime.
This guideline is divided into three parts:
- Introduction to different application firewall rules.
- Instructions on configuring the rules using the Portal or Bicep on the SignalR service side.
- Steps to configure the token on the server side.
- An Azure SignalR Service in Premium tier.
Client Connection Count Rules restrict concurrent client connections. When a client attempts to establish a new connection, the rules are checked sequentially. If any rule is violated, the connection is rejected with a status code 429.
This rule limits the concurrent connections of a user. For example, if a user opens multiple browser tabs or logs in using different devices, you can use this rule to restrict the number of concurrent connections for that user.
Note
- The UserId must exist in the access token for this rule to work. Refer to Configure access token.
This rule limits the concurrent connections of the same token to prevent malicious users from reusing tokens to establish infinite connections, which can exhaust connection quota.
Note
- It's not guaranteed by default that tokens generated by the SDK are different each time. Though each token contains a timestamp, this timestamp might be the same if vast tokens are generated within seconds. To avoid identical tokens, insert a random claim into the token claims. Refer to Configure access token.
More advanced, connections could be grouped into different groups according to custom claim. Connections with the same claim are aggregated to do the check. For example, you could add a ThrottleByJwtCustomClaimRule to allow 5 concurrent connections with custom claim name freeUser.
Note
- The rule applies to all claims with a certain claim name. The connection count aggregation is on the same claim (including claim name and claim value). The ThrottleByUserIdRule is a special case of this rule, applying to all connections with the userIdentity claim.
Warning
- Avoid using too aggressive maxCount. Client connections may close without completing the TCP handshake. SignalR service can't detect those "half-closed" connections immediately. The connection is taken as active until the heartbeat failure. Therefore, aggressive throttling strategies might unexpectedly throttle clients. A smoother approach is to leave some buffer for the connection count, for example: double the maxCount.
Client Traffic Control Rules restrict the inbound throughput of client connections. When a client attempts to send a message, the rules are checked sequentially. Within each aggregation window, the message size will be aggregated to check against max inbound message. If any rule is violated, the connection is disconnected.
This rule limits the inbound throughput of a user.
This rule limits the inbound throughput of each token.
This rule limits the inbound throughput of the same claim.
To use Application Firewall, navigate to the SignalR Application Firewall blade on the Azure portal and click Add to add a rule.
The application firewall rules only take effect when the access token contains the corresponding claim. A rule is skipped if the connection does not have the corresponding claim.
Below is an example to add userId or custom claim in the access token in Default Mode:
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"]),
};
});
The logic for Serverless Mode is similar.
For more details, refer to Client negotiation .