-
Notifications
You must be signed in to change notification settings - Fork 10.3k
SecurityTokenMalformedException after updating to .NET 8 #52286
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
Comments
Looks like a duplicate of #52099. |
Based on #52099 I went to Security token events return a JsonWebToken and added
@martincostello Any ideas why the recommended option does not work? |
I'm afraid not - maybe it's a bug in IdentityModel. See #52099 (comment). |
@martincostello can you guide me to a sample code that shows me how to rewrite my entire security to match .NET 8? I mean, instead of me trying to make .NET 8 work for my old way, I want to upgrade to the new |
Sorry, I'm not aware of such a sample - someone from the ASP.NET Core team should be able to help you when they come online later today. |
@Nefcanto would it be possible to obtain a sample token that is failing? |
@brentschmaltz we're using Keycloak, and we tested its token using jwt.io, and it was valid. I can create a test user and create a token to paste here. Actually I had pasted a token in the original post and it's in the edit history. Can you see it? |
@martincostello @Nefcanto #52099 is clearly an issue which needs to be address. |
@martincostello I was able to obtain the token from history. |
@martincostello i was able to create a new JsonWebToken using the jwt i found, so the jwt is indeed well-formed. |
@brentschmaltz thank you for helping. I think it's an internal thing related to the .NET itself. We don't have |
I'm running into the exact same error. |
I faced the same problem, and now I will describe my solution to the problem. If you try to validate the token using the standard means that the library implies, you will get an error. builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,,
};
}); I decided this because the main method of token validation, which the library assumes, produces a similar error when trying to validate a valid JWT token. var jwtTokenString = "paste_your_correct_token_here";
var validationParams = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,
};
var tokenHandler = new JwtSecurityTokenHandler();
await tokenHandler.ValidateTokenAsync(jwtTokenString, validationParams);
// Exception: IDX14100: JWT is not well formed, there are no dots (.) Based on what I was able to find on the Internet, the problem manifests itself on .NET Core 8.0, and it can be solved if you use an older version of The validator code that I wrote: public class BearerTokenHandler : TokenHandler
{
private readonly JwtSecurityTokenHandler _tokenHandler = new();
public override Task<TokenValidationResult> ValidateTokenAsync(string token, TokenValidationParameters validationParameters)
{
try
{
_tokenHandler.ValidateToken(token, validationParameters, out var validatedToken);
if (validatedToken is not JwtSecurityToken jwtSecurityToken)
return Task.FromResult(new TokenValidationResult() { IsValid = false });
return Task.FromResult(new TokenValidationResult
{
IsValid = true,
ClaimsIdentity = new ClaimsIdentity(jwtSecurityToken.Claims, JwtBearerDefaults.AuthenticationScheme),
// If you do not add SecurityToken to the result, then our validator will fire, return a positive result,
// but the authentication, in general, will fail.
SecurityToken = jwtSecurityToken,
});
}
catch (Exception e)
{
return Task.FromResult(new TokenValidationResult
{
IsValid = false,
Exception = e,
});
}
}
} In the end, you only need to connect your own validator. builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,
};
options.TokenHandlers.Add(new BearerTokenHandler()); // <---
}); Thus, we bypassed the error and did not use the deprecated Write your thoughts on this, and excuse my English (I used a translator). |
Just to add a couple of thoughts here, as I'm battling with JWT authentication since upgrading to 8.x this week. There doesn't seem to be any complete end to end official examples of how to implement JWT using the newer The breaking changes from 7.x -> 8.x were documented, with workarounds (that did not work) and did not contain enough information for users to create an updated end to end solution. Coupled with the difficulty in debugging the built in solution and the end result is a large number of developers creating workarounds and custom implementations for a complex security protocol, which is supposed to be standardised to stop buggy "roll your owns". I'll be reverting to 7.x after creating my own 8.x implementation, only to find it can't validate a perfectly valid token (as confirmed by jwt.io). Dead ends everywhere SMH. |
I should provide an example for repro;
|
also getting the inner exception is more accurate on this - in my case, the issue being the several fields (such as |
I was able to solve this by updating this code
to
and here is all dependencies package relate to jwt
|
I was able to solve this along @migajek lines:
I was setting the issued at (iat) claim using |
I am struggling with this issue. I checked in nuget and I have 8.0.2. So I am guessing this is not fixed yet? In my case, my PWA WASM blazor app talks fine with jwt to my server API. The problem is I have javascript code too in the PWA, but when I post the exact same jwt string in that, i get an auth error. Have quadruple checked and all looks good. If I remove the [Authorize] from my controller, the javascript works fine. I have tried with and without "Bearer " in front of token, still doesn't work. So I am guessing there is something wrong in the format of the header, maybe it changed, but since I have .NET 8 on pwa and the server API, they cancel each other out by both writing and understanding bad header syntax, but the header on the javascript doesn't work because it's correct. |
Just to update, I finally figured out my issue. It seemed that when I retrieve the token string from localstorage in javascript, it comes out with a double quote at start and finish. It seems the PWA retrieving from local storage doesn't get that. So I simply added code in my javascript to remove double quotes from the string:
Hopefully this might help someone else. |
Certainly! When upgrading from .NET 6 to .NET 8, I encountered an issue related to setting the "issued at" (iat) claim. Initially, I was using
|
This is a really nasty issue. Our tokens (which validated fine in jwt.io) were failing to validate for seemingly no reason after upgrading from dotnet 7 to dotnet 8. Even with {
"Logging": {
"LogLevel": {
"Microsoft.AspNetCore.Authentication": "Information",
}
}
} We were able to see the following incredibly misleading message:
This was despite the fact that our tokens definitely had dots. I even double-checked to make sure it wasn't some weird unicode character that just looked like a dot. Searching the internet for Stackoverflow suggested setting builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opts =>
{
opts.UseSecurityTokenValidators = true;
}); However, the docs suggest this isn't as performant as the default of @natelowry 's solution of installing
I think some sort of check needs to be added on startup to make sure that the appropriate package is installed when |
Thanks, it's work in my project |
@dzerenus This works fine, having a custom validator solves the problem. Thanks for sharing. It is important to point out though that the SecurityToken should be the validatedToken. That is |
Had the same issue some weeks ago, upgraded the token libraries to version 7.6.0 and now it's working
|
I guess I'm not at the right place, but maybe someone could redirect me. I think I have the token figured out. I get an access_token from my vue.js app provided by MSAL, then in my API I UTF8 Base64 encode it and send it with the request to Azure DevOps API. Now I'm getting a 203 - "Non-Authoritative Information" with an HTML file. Any help would be appriciated! |
Microsoft.IdentityModel.Tokens.SecurityTokenMalformedException: IDX14100: JWT is not well formed, there are no dots (.). |
I have the same issue with Microsoft.AspNetCore.Authentication.JwtBearer; version 8.0.6 OnMessageReceived = context =>
} |
thank you very much |
Works fine with me |
I also had to add the packages Microsoft.IdentityModel.JsonWebTokens and Microsoft.IdentityModel.Tokens. |
I have: 'Microsoft.AspNetCore.Authentication.JwtBearer' version '8.0.8' something is still broken, as soon as I turn on:
I get: Authentication failed: IDX10225: Lifetime validation failed. The token is missing an Expiration Time. Tokentype: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'. while jwt.io recognizes the "exp" property correctly:
When I set: then my API works fine... |
After installing 'Microsoft.IdentityModel.JsonWebTokens (8.0.2)' I now have the following packages: Microsoft.IdentityModel.Tokens (8.0.2), Then, I set ValidateLifetime = false (it was originally true) it works fine. |
it works fine but if you consider the nature of jwt it is completely wrong. You should revert to the previous version |
This worked as a charm! Thanks! |
I had the same issue migrating dotnet6 to dotnet8 . |
I had this issue after bumping some dependencies already on dotnet8. It turns out that my issue was incompatible versions of installed and transitive dependencies in Microsoft.IdentityModel.*. Make sure they're all the same version. It seems to me that it was the Microsoft.AspNetCore.Authentication.JwtBearer that was referencing Microsoft.IdentityModel.OpenIdConnect with a different (a lesser major) version compared to the other packages I had installed. I solved it by explicitly installing the transitive dependent packages with the same version as the other Microsoft.IdentityModel packages I had installed. |
GOOD,thanks |
Uh oh!
There was an error while loading. Please reload this page.
Is there an existing issue for this?
Describe the bug
I know #52191 is about the same error. But in my case, my JWT is created via Keycloak and I can verify it at https://jwt.io/.
This is the error I get after upgrading to .NET 8 and upgrading my package reference to
8.0.0
:Expected Behavior
No response
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
No response
Anything else?
No response
The text was updated successfully, but these errors were encountered: