Closed tehho closed 8 months ago
@tehho which OIDC provider are you using?
@keegan-caruso Curity. We have got it down to the mtls_endpoint_aliases post in the config causing the issue. https://curity.io/resources/learn/oidc-spring-boot-mtls-auth/ https://datatracker.ietf.org/doc/html/rfc8705#name-metadata-for-mutual-tls-end
@tehho can you provide a sample of the json that is causing you an issue?
@tehho can you provide a sample of the json that is causing you an issue?
@brockallen @tehho the reason i asked is because i debugged using that code and didn't see the issue. Did i simplify the metadata too much?
@brentschmaltz possibly. The issue we've seen is when jwks_uri is below the mtls_endpoint_aliases object. But any object before the jwks_uri should trigger the problem.
A zipped solution with an example. jwks-8.0.zip
@tehho thanks.
@tehho Yep, you called it. We get away with arrays as the exist condition is JsonTokenType.EndObject, JsonTokenType.EndArray is just gobbled up.
With Objects, we bail early.
Nice Demo code :-)
Will get this fixed.
Maybe I am missing something but wouldn't is work just to remove the if statement at the bottom checking for JsonTokenType.EndObject, to me it seems that this is a somewhat unnecessary optimization as the file should be done reading the next iteration anyway? This will avoid the complexity of skipping/handling objects, also unknown property-names are already stored in the AdditionalData property even if it is an object.
This is such a painful bug. I am seeing people doing crazy workarounds, like specifying all the values of configuration explicitly in the configuration.
I believe the correct solution is to move it as the first thing after the read - when object is read, the reader is positioned at the end of that object. So after the read in the while cycle it will move to the next element. Besides, if it is the end of the configuration, there is no reason to perform some analysis of that element before stopping the serialization - so doing that at the end is counterintuitive anyways.
while (reader.Read())
{
if (IfJsonSerializerPrimitives.IsReaderAtTokenType(ref reader, JsonTokenType.EndObject, false))
{
break;
}
Probably the hardest part would be to straighten the tests. As I tried to do it, I bumped against RoundTripFromJson tests, where AdditionalData objects undergo a transformation (loosing the indentations used in test data) - comparer tests differences by comparing strings, so it will fail even if a single whitespace is different.
Looks that there is a bug in jsonelement comparer, where indents (whitespaces) between elements has impact on the comparison result. E.g. {{ "p": "v"}} is considered to be different from {{"p":"v"}}
When is this going to be fixed? This bug is causing serious issues with authentication.
If it helps in any way solving the bug, I've conducted some experiments that might be helpful. These include a scenario where a certain setup leads to only part of the configuration being read.
@bgirts @ClassyCircuit @tehho @unger @brockallen this has been fixed in this PR. Hope to have a release out soon.
@brentschmaltz I still have trouble with 8.0.3 - is it supposed to be fixed in that version?
@AThomsen installing explicitly Microsoft.AspNetCore.Authentication.OpenIdConnect nuget package 8.0.3 solved issue on my side
Note to others coming here:
It's only necessary to include Microsoft.IdentityModel.Protocols.OpenIdConnect
(7.5.2 or later), not Microsoft.AspNetCore.Authentication.OpenIdConnect
.
It would be great if MS would update Microsoft.AspNetCore.Authentication.JwtBearer
to depend on the updated version!
Which version of Microsoft.IdentityModel are you using? Note that to get help, you need to run the latest version.
.net 8.0
Where is the issue?
Is this a new or an existing app? New for .net 8.0
Repro
Expected behavior Be able to read .well-known/openid-configuration with object that does not affect OIDC config
Actual behavior Ends reading config on the first }. This stops the read of the rest of the config and in our case ignored the jwks endpoint setting.
Possible solution Ignore unknown objects with a while read loop
Additional context / logs / screenshots / links to code