Skip to content

Conversation

@halter73
Copy link
Contributor

IDX14100 makes sense when it is thrown from JsonWebToken constructor or Read method when there is really one dot, but not as a generic error message any time there is a token validation failure for any reason.

IDX14100: JWT is not well formed, there are no dots (.).\nThe token needs to be in JWS or JWE Compact Serialization Format. (JWS): 'EncodedHeader.EncodedPayload.EncodedSignature'. (JWE): 'EncodedProtectedHeader.EncodedEncryptedKey.EncodedInitializationVector.EncodedCiphertext.EncodedAuthenticationTag'.

Dot1 = encodedTokenSpan.IndexOf('.');
if (Dot1 == -1 || Dot1 == encodedTokenSpan.Length - 1)
throw LogHelper.LogExceptionMessage(new SecurityTokenMalformedException(LogMessages.IDX14100));

The above line seems to be the only correct usage of the IDX14100, and it remains after this PR. IDX14120 gives a more precise error message when a "JWT is not well formed, there is only one dot", but that winds up getting wrapped in another exception with the incorrect IDX14100 message and relogged by JsonWebTokenHandler.ReadToken. Other validation errors like a non-numeric "iat" claim also result get the incorrect IDX14100 message.

info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[1]
      Failed to validate the token.
      Microsoft.IdentityModel.Tokens.SecurityTokenMalformedException: IDX14100: JWT is not well formed, there are no dots (.).
The token needs to be in JWS or JWE Compact Serialization Format. (JWS): 'EncodedHeader.EndcodedPayload.EncodedSignature'. (JWE): 'EncodedProtectedHeader.EncodedEncryptedKey.EncodedInitializationVector.EncodedCiphertext.EncodedAuthenticationTag'.
       ---> System.ArgumentException: IDX14101: Unable to decode the payload '[PII of type 'Microsoft.IdentityModel.Logging.SecurityArtifact' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' as Base64Url encoded string.
       ---> System.Text.Json.JsonException: IDX11020: The JSON value of type: 'String', could not be converted to 'JsonTokenType.Number'. Reading: 'Microsoft.IdentityModel.JsonWebTokens.JsonWebToken.iat', Position: '52', CurrentDepth: '1', BytesConsumed: '75'.
         at Microsoft.IdentityModel.Tokens.Json.JsonSerializerPrimitives.ReadLong(Utf8JsonReader& reader, String propertyName, String className, Boolean read)
         at Microsoft.IdentityModel.JsonWebTokens.JsonWebToken.CreatePayloadClaimSet(Byte[] bytes, Int32 length)
         at Microsoft.IdentityModel.Tokens.Base64UrlEncoding.Decode[T](String input, Int32 offset, Int32 length, Func`3 action)
         at Microsoft.IdentityModel.JsonWebTokens.JsonWebToken.CreateClaimSet(String rawString, Int32 startIndex, Int32 length, Func`3 action)
         at Microsoft.IdentityModel.JsonWebTokens.JsonWebToken.ReadToken(String encodedJson)
         --- End of inner exception stack trace ---
         at Microsoft.IdentityModel.JsonWebTokens.JsonWebToken.ReadToken(String encodedJson)
         at Microsoft.IdentityModel.JsonWebTokens.JsonWebToken..ctor(String jwtEncodedString)
         at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ReadToken(String token, TokenValidationParameters validationParameters)
         --- End of inner exception stack trace ---

This exception wrapping by JsonWebTokenHandler.ReadToken seems to serve no purpose other than make it appear that the token is invalid for the wrong reason. The original reporter pointed out that this was obscuring an exception caused by deleting System.Buffers.dll. While this isn't something a developer should do, it demonstrates why wrapping arbitrary exceptions is bad in this scenario. Even if the issue really was what is described by IDX14100, JsonWebTokenHandler.ReadToken still unnecessary wraps that with an identical outer exception and logs it a second time.

The change to use a custom ArgumentException rather than an IDX14100 SecurityTokenMalformedException when JsonWebTokenHandler.ValidateTokenAsync gets a non-JsonWebToken SecurityToken is less important, but it is another place IDX14100 is being used that has nothing to do with the number of dots in the token. I don't think we should be logging ArgumentExceptions at all, but I continue logging in order to stick to the conventions of the library. If we make a change to not log ArgumentExceptions, we should probably do that everywhwere.

Fixes #2058

@halter73 halter73 requested a review from a team as a code owner May 29, 2024 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Unhelpful error message with missing dependency for System.Buffers

4 participants