[csharp] Fix HTTP signature auth failure on .NET 8 when query params contain special characters#23714
Conversation
98c1c14 to
76934f8
Compare
|
thanks for the PR cc @mandrean (2017/08) @shibayan (2020/02) @Blackclaws (2021/03) @lucamazzanti (2021/05) @iBicha (2023/07) |
| // characters (e.g. '$' in OData params like $filter) are encoded the same way | ||
| // in the signature as they are in the outgoing HTTP request. | ||
| string framework = RuntimeInformation.FrameworkDescription; | ||
| bool skipUrlEncode = framework.StartsWith(".NET ") && |
There was a problem hiding this comment.
what about declaring this boolean flag similar to SigningAlgorithm (a property of this class) and initialize it in the constructor to avoid computing the value every time this function is called?
There was a problem hiding this comment.
refactored skipUrlEncode from a local variable in GetHttpSignedHeader to a private readonly bool _skipUrlEncode field initialized once in the constructor. This avoids recomputing the runtime version check on every call.
…ncoding in HTTP signature The HttpSigningConfiguration template used the Mustache conditional net90OrLater to decide whether to URL-encode query parameter keys. When targeting net8.0, this conditional evaluates to false and the UrlEncode call is omitted entirely, producing an unencoded key in the signature base string. However, RestSharp 112+ always sends URL-encoded query parameters on the wire, causing a signature mismatch and HTTP 401 on every request that contains special characters in query parameter names (e.g. OData \, \, \). Replace the compile-time Mustache conditional with runtime detection using RuntimeInformation.FrameworkDescription. On .NET 9+ the key is left as-is (ParseQueryString already encodes internally); on .NET 8 and earlier, HttpUtility.UrlEncode is called explicitly so the signature matches the actual request.
76934f8 to
b56455a
Compare
|
This is great, thanks for the fix! Consider another change to remove the duplicated code in the precompile directive |
Summary
Replace compile-time Mustache
{{#net90OrLater}}conditional with runtime .NET version detection for URL-encoding query parameter keys in HTTP signature computation.Problem
When targeting
net8.0, the{{#net90OrLater}}Mustache conditional evaluates to false, causingHttpUtility.UrlEncode()to be completely omitted from the generatedHttpSigningConfiguration.cs. The generated code becomes:Meanwhile, RestSharp 112+ always URL-encodes query parameters on the wire. This mismatch means the HTTP signature is computed over unencoded keys (e.g. $filter) while the actual request sends encoded keys (e.g. %24filter), resulting in HTTP 401 on every request with special characters in query parameter names (OData $filter, $top, $orderby, etc.).
Solution:
Use RuntimeInformation.FrameworkDescription to detect the .NET major version at runtime:
.NET 9+: Skip explicit URL-encoding (HttpUtility.ParseQueryString already encodes keys internally on .NET 9+, so encoding again would cause double-encoding)
.NET 8 and earlier: Explicitly call HttpUtility.UrlEncode(parameter.Key) so the signature matches what RestSharp sends
PR checklist
Read the contribution guidelines.
Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
Run the following to build the project and update samples:
File the PR against the correct branch: master
If your PR is targeting a particular programming language, @mention the technical committee members for that language.
@muttleyxd @devhl-labs @lucasheim @shibayan (C# generators)
Summary by cubic
Fixes HTTP signature auth failures on .NET 8 and ensures correct behavior on .NET 9+ when query parameter names contain special characters by aligning URL-encoding with the actual request. We now detect the .NET version at runtime to decide whether to URL-encode query keys.
{{#net90OrLater}}with runtime detection viaRuntimeInformation.FrameworkDescription.RestSharp112+ requests.HttpSigningConfigurationtemplate and regenerated C# samples (httpclient,restsharp,unityWebRequest).Written for commit b56455a. Summary will update on new commits.