AzureAD / azure-activedirectory-identitymodel-extensions-for-dotnet

IdentityModel extensions for .Net
MIT License
1.06k stars 400 forks source link

[Bug] project update to net8.0, after the jwt "System.IdentityModel.Tokens.Jwt 7.0.3" throw an error : “IDX12723: Unable to decode the payload \u0027[PII of type \u0027System.String\u0027 is hidden. For more details, see https://aka.ms/IdentityModel/PII.]\u0027 as Base64Url encoded string.” #2401

Open andrew2558 opened 11 months ago

andrew2558 commented 11 months ago

Which version of Microsoft.IdentityModel are you using? Note that to get help, you need to run the latest version. Microsoft.AspNetCore.Authentication.JwtBearer 8.0.0 System.IdentityModel.Tokens.Jwt 7.0.3

Where is the issue?

Is this a new or an existing app? a. The app is in production and I have upgraded to a new version of Microsoft.IdentityModel.*

Repro

var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken securityToken);

Expected behavior code run success

Actual behavior throw an error: “IDX12723: Unable to decode the payload \u0027[PII of type \u0027System.String\u0027 is hidden. For more details, see https://aka.ms/IdentityModel/PII.]\u0027 as Base64Url encoded string.”

Possible solution

Additional context / logs / screenshots / links to code

 在 System.IdentityModel.Tokens.Jwt.JwtSecurityToken.DecodeJws(String payload)
   在 System.IdentityModel.Tokens.Jwt.JwtSecurityToken.Decode(String[] tokenParts, String rawData)
   在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ReadJwtToken(String token)
   在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.GetJwtSecurityTokenFromToken(String token, TokenValidationParameters validationParameters)
   在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateJWS(String token, TokenValidationParameters validationParameters, BaseConfiguration currentConfiguration, SecurityToken& signatureValidatedToken, ExceptionDispatchInfo& exceptionThrown)
--- 上一位置中堆栈跟踪的末尾 ---
   在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, JwtSecurityToken outerToken, TokenValidationParameters validationParameters, SecurityToken& signatureValidatedToken)
   在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
jennyf19 commented 11 months ago

Are all of your M.IM.* packages on the same version?

andrew2558 commented 11 months ago

Are all of your M.IM.* packages on the same version?

System.IdentityModel.Tokens.Jwt 7.0.3 other M.IM.* packages 8.0.0

AdamWeberQB commented 10 months ago

I am seeing this problem too. All I did was upgrade from 6.27.0 to 7.0.3 and I got the failure.

keegan-caruso commented 9 months ago

Can you provide any more details? This isn't quite enough to reproduce.

Neralem commented 9 months ago

Got the same Issue after upgrading from 6.23.1 to 7.0.3. 7.20.0 still has this problem. Going back to 6.23.1 works for now. Can not reproduce the problem on all machines...

Neralem commented 8 months ago

Sadly I dont have the stacktrace anymore but the one that the OP posted is somewhat missleading I think. I remember I've read something about a MissingMethodException in relation to System.Text.Json.Utf8JsonReader

digiofficerobin commented 8 months ago

I have a similar message:

IDX12723: Unable to decode the payload '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' as Base64Url encoded string.

In the debugger I found this message: IDX11020: The JSON value of type: 'Number', could not be converted to 'JsonTokenType.String'. Reading: 'System.IdentityModel.Tokens.Jwt.JwtPayload.jti', Position: '144', CurrentDepth: '1', BytesConsumed: '145'.'

The payload which is trying to be parsed is (I've masked name and preferred_username).

{ "iss": "ssjwt", "sub": null, "iat": 1707237670, "exp": 1707241270, "name": "xxxxxx@xxxxxxxx", "preferred_username": "xxxxxxxx@xxxxxxxxxxx", "jti": 4, "OriginalProvider": "msalauth" }

I think the issue is the "jti" claim which is returned as a number instead of a string by the ServiceStack service. I've checked with older versions of the ServiceStack service, and it has always been a number.

In JwtPayload.cs the following code snippet is reading the value as a string instead of a number:

else if (reader.ValueTextEquals(JwtPayloadUtf8Bytes.Jti)) { payload._jti = JsonSerializerPrimitives.ReadString(ref reader, JwtRegisteredClaimNames.Jti, ClassName, true); payload[JwtRegisteredClaimNames.Jti] = payload._jti; }

Is this an intended breaking change and should ServiceStack be updated?

keegan-caruso commented 8 months ago

@digiofficerobin

JTI per the RFC is a string.

See here

Please open a separate issue specifically around ServiceStack compatibility,

digiofficerobin commented 8 months ago

@digiofficerobin

JTI per the RFC is a string.

See here

Please open a separate issue specifically around ServiceStack compatibility,

Oke, thanks, I'll contact the ServiceStack team for this issue.

brentschmaltz commented 7 months ago

@digiofficerobin did you hear from ServiceStack? I would like to know if this issue of JTI as a Json.Number is common.

I marked it as a regression from 6x to 7x, doesn't mean we will fix it :-)

digiofficerobin commented 7 months ago

@digiofficerobin did you hear from ServiceStack? I would like to know if this issue of JTI as a Json.Number is common.

I marked it as a regression from 6x to 7x, doesn't mean we will fix it :-)

Yes, I had an answer/workaround the same day. I had to override the ResolveJwtId and ResolveRefreshJwtId in the JwtAuthProvider to generate a GUID as a string.

See my post on Stack overflow: https://stackoverflow.com/questions/77953167/idx11020-the-json-value-of-type-number-could-not-be-converted-to-jsontoken

brentschmaltz commented 7 months ago

@digiofficerobin thanks! While JTI should be a String, per spec, I don't see any security issues with attempting to map the Number (int or long) to a String. I hesitate for floating point.

I will leave the issue open.

digiofficerobin commented 7 months ago

In the past, a Number wasn't an issue. Which is a breaking change. That may not cause a problem if this is communicated well in the release notes of the NuGet package.

brentschmaltz commented 7 months ago

@digiofficerobin considering this is not completely in the users control as they receive metadata from a 3rd party, this may break users for a period of time they can't control. Sometimes IdentityProviders refuse to change as a change will break other users.

We strive to have users upgrading without issues as we are constantly improving the product. I am going to ask the team to make this change.

tomkerkhove commented 5 months ago

We've had a regression because of this as well, trying to get a repro to see asap