Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SecurityTokenMalformedException after updating to .NET 8 #52191

Closed
1 task done
msallin opened this issue Nov 19, 2023 · 7 comments
Closed
1 task done

SecurityTokenMalformedException after updating to .NET 8 #52191

msallin opened this issue Nov 19, 2023 · 7 comments
Labels
External This is an issue in a component not contained in this repository. It is open for tracking purposes.

Comments

@msallin
Copy link

msallin commented Nov 19, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I updated my application to .NET 8 and hence also from Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.13" to Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0". This breaks my authentication mechanism.

I turned on the logs that may show the necessary information.

Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware: Debug: Request matched endpoint 'FreshCube.MinimalOrdering.Web.Application.UserManagement.Controllers.UsersController.Get (FreshCube.MinimalOrdering.Web)'
'FreshCube.MinimalOrdering.Web.exe' (CoreCLR: clrhost): Loaded 'C:\work\fresh-cube\minimal-ordering\src\FreshCube.MinimalOrdering.Web\bin\Debug\net8.0\Microsoft.IdentityModel.Abstractions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Information: 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: '185', CurrentDepth: '1', BytesConsumed: '213'.
   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 ---
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Information: Bearer was not authenticated. Failure message: 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'.
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware: Debug: Static files was skipped as the request already matched an endpoint.
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware: Debug: Policy authentication schemes  did not succeed
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed. These requirements were not met:
DenyAnonymousAuthorizationRequirement: Requires an authenticated user.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Information: AuthenticationScheme: Bearer was challenged.
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished HTTP/2 GET https://localhost:7085/api/users/profile - 401 0 - 84.1440ms

I send the following request:

curl -X 'GET' \
  'https://localhost:7085/api/users/profile' \
  -H 'accept: text/plain' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5mcmVzaGN1YmUuY29tL1VzZXJJZCI6IjNiNjUyOTM3LTUwMzMtNGIxNS04YTFkLTFkZjNmMDY5NjE2NiIsImVtYWlsIjoiYWRtaW5AZnJlc2hjdWJlLmNoIiwic3ViIjoiYWRtaW5AZnJlc2hjdWJlLmNoIiwianRpIjoiZjcxZGE2NGEtNDVmOS00NDhiLWFlODAtNjI3N2ExY2JjMzMyIiwiaWF0IjoiMTEvMTkvMjAyMyA4OjMzOjM2XHUyMDJGQU0iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJhZG1pbiIsIm5iZiI6MTcwMDM4MjgxNiwiZXhwIjoxNzAyOTc0ODE2LCJpc3MiOiJGcmVzaEN1YmUiLCJhdWQiOiJGcmVzaEN1YmUifQ.4xoyMXVXZo1wpoByrSlfbQTfLSCSNB_g9F7mxsxfc1w'

Expected Behavior

The authentication works. When there is a breaking change, that should be documented.

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

8.0

Anything else?

No response

@Kahbazi
Copy link
Member

Kahbazi commented Nov 19, 2023

I think this might be the problem.

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: '185', CurrentDepth: '1', BytesConsumed: '213'.

The jwt that you are sending in the request has iat claim with this value: 11/19/2023 8:33:36 AM

Based on the RFC 7519 this claim MUST be number.

This is probably an issue with this repo. https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet

@mkArtakMSFT
Copy link
Member

Thanks for handling this, @Kahbazi !

@mkArtakMSFT mkArtakMSFT closed this as not planned Won't fix, can't repro, duplicate, stale Nov 21, 2023
@mkArtakMSFT mkArtakMSFT added the External This is an issue in a component not contained in this repository. It is open for tracking purposes. label Nov 21, 2023
@teslavitas
Copy link

I have the same issue, downgrading Microsoft.AspNetCore.Authentication.JwtBearer to 7.0.14 helped.

@msallin
Copy link
Author

msallin commented Nov 24, 2023

I fixed the issue. The issue was actually in my code because I added iat manually as claim but used a ToString on DateTime there. It worked like that so far. Now I changed it to the following:

new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(now).ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Integer64)

@LarsWesselius
Copy link

LarsWesselius commented Dec 8, 2023

Took me a while to find out but just to provide some context: previously, in .NET 7 the iat parsing was more forgiving. See this diff of JwtPayload where GetDateTime was removed, I believe this method was used to parse iat before.

Now, quite clearly iat parser expects a number as per the standard. See this file. So as mentioned by @msallin, can be fixed by using EpochTime or

new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString())

@muhammad-abdulloh
Copy link

I fixed the issue. The issue was actually in my code because I added iat manually as claim but used a ToString on DateTime there. It worked like that so far. Now I changed it to the following:

new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(now).ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Integer64)

Wery Useful Thanks man

@kokosky93
Copy link

I am facing the same issue. Changing Iat claim didn't help :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
External This is an issue in a component not contained in this repository. It is open for tracking purposes.
Projects
None yet
Development

No branches or pull requests

7 participants