microsoft-identity-web
microsoft-identity-web copied to clipboard
downstreamApi does not correctly handle text response
Microsoft.Identity.Web Library
Microsoft.Identity.Web.DownstreamApi
Microsoft.Identity.Web version
2.17,1
Web app
Not Applicable
Web API
Protected web APIs call downstream web APIs
Token cache serialization
Not Applicable
Description
downstreamApi will attempt to deserialize JSON, even if expected return type is a string.
The only way I have been able to get around this, is by setting up a synchronous custom deserializer as follows:
options.Deserializer = (content) =>
{
var task = Task.Run(() => content.ReadAsStringAsync());
task.Wait();
return task.Result;
};
Reproduction steps
Create a downstream API service that return raw text (i.e., not JSON encoded text). Then call that API using:
var result = await _downstreamApi.PostForAppAsync<object, string>( "MyApi", null);
Error message
'r' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
System.Text.Json.JsonException: 'r' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
---> System.Text.Json.JsonReaderException: 'r' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker)
at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first)
at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
at System.Text.Json.Utf8JsonReader.Read()
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
Id Web logs
No response
Relevant code snippets
result = await _downstreamApi.PostForAppAsync<object, string>("MyApi", null);
Regression
No response
Expected behavior
I would expect the downstreamApi to not attempt to parse content if the expected return value is of type string
Hi @karlschriek - there are methods that return an HttpResponseMessage
instead, that do not parse the message content. Can't those be used instead?
https://github.com/AzureAD/microsoft-identity-web/blob/master/src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs#L77
Using the overrides returning an HttpResponseMessage is a work around.
However, we could do better in the other overrides: we should respect the Content-Type header provided by the web API when it's provided. If it contains json we deserialize. If it's text
additionally we should expose a new property "acceptHeader" in the DownstreamApiOptions to specify what the client can process. @jennyf19: it's a good first issue. .NET 9?