-
Notifications
You must be signed in to change notification settings - Fork 10k
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
Update JwtBearer, WsFed, and OIDC handlers to use identity model 7 #49542
Update JwtBearer, WsFed, and OIDC handlers to use identity model 7 #49542
Conversation
Co-authored-by: Brent Schmaltz <brentsch@hotmail.com>
remove using System
Co-authored-by: Keegan Caruso <keegancaruso@microsoft.com>
* SymmetricSecurityKey needs 32 bytes * Update source-build-externals dependencies --------- Co-authored-by: Keegan Caruso <keegancaruso@microsoft.com>
* Update Wilson7 branch Default to using new handlers Changes from API review * Handle obsolete members * Handle obsolete members in tests * Add aka.ms link --------- Co-authored-by: Keegan Caruso <keegancaruso@microsoft.com>
…/wilson7-consolidated
Thanks for your PR, @keegan-caruso. Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
Hi @keegan-caruso. Please make sure you've updated the PR description to use the Shiproom Template. Also, make sure this PR is not marked as a draft and is ready-to-merge. To learn more about how to prepare a servicing PR click here. |
Hi @keegan-caruso. This PR was just approved to be included in the upcoming servicing release. Somebody from the @dotnet/aspnet-build team will get it merged when the branches are open. Until then, please make sure all the CI checks pass and the PR is reviewed. |
|
||
namespace Microsoft.AspNetCore.Authentication.JwtBearer; | ||
|
||
public class JwtBearerTests_Handler : SharedAuthenticationTests<JwtBearerOptions> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any way to refactor these tests so they can be shared with the existing JwtBearerTests? For example having a base test class with the tests in them?
May be something to think about as a follow-up refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed it would be a good follow up
@@ -103,8 +113,14 @@ public new JwtBearerEvents Events | |||
/// <summary> | |||
/// Gets the ordered list of <see cref="ISecurityTokenValidator"/> used to validate access tokens. | |||
/// </summary> | |||
[Obsolete("SecurityTokenValidators is no longer used by default. Use TokenHandlers instead. To continue using SecurityTokenValidators, set UseSecurityTokenValidators to true. See https://aka.ms/aspnetcore8/security-token-changes")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Tratcher @halter73 @captainsafia - what do you think about defining a new DiagnosticId
for this obsoletion? That way people who are using SecurityTokenValidators, and want to keep using it, don't need to suppress CS0618
(the catch-all obsolete ID), and instead can just globally suppress the specific ASP1234
ID. Then we could do the same in our tests and not need to #pragma warning disable
everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s do this for rc1. @keegan-caruso - can you log a follow up issue for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (Options.ConfigurationManager != null) | ||
{ | ||
// GetConfigurationAsync has a time interval that must pass before new http request will be issued. | ||
_configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does the WsFederationHandler still cache the configuration in a field, but the JwtBearer doesn't?
See also the conversation at #48966 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can make the same change to this handler if you want. It made sense to remove the field in JwtBearer to clean up the code. It was just being read in one place.
Was trying to make less changes to WsFed where possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Let’s make a follow up change in main for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mainly nits since I'm not super familiar with the area
@@ -135,4 +135,10 @@ | |||
<data name="IdTokenCodeMissing" xml:space="preserve"> | |||
<value>Cannot process the message. Both id_token and code are missing.</value> | |||
</data> | |||
<data name="ValidatedSecurityTokenNotJsonWebToken" xml:space="preserve"> | |||
<value>The Validated Security Token must be of type JsonWebToken, but instead its tye is '{0}'.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<value>The Validated Security Token must be of type JsonWebToken, but instead its tye is '{0}'.</value> | |
<value>The Validated Security Token must be of type JsonWebToken, but instead its type is '{0}'.</value> |
/// <summary> | ||
/// Gets or sets the <see cref="TokenHandler"/> used to validate identity tokens. | ||
/// <para> | ||
/// This will be used instead of <see cref="SecurityTokenValidator"/> if <see cref="UseSecurityTokenValidator"/> is <see langword="false"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// This will be used instead of <see cref="SecurityTokenValidator"/> if <see cref="UseSecurityTokenValidator"/> is <see langword="false"/> | |
/// This will be used instead of <see cref="SecurityTokenValidator"/> if <see cref="UseSecurityTokenValidator"/> is <see langword="false"/>. |
[LoggerMessage(56, LogLevel.Error, "Unable to validate the 'id_token', no suitable TokenHandler was found for: '{IdToken}'.", EventName = "UnableToValidateIdTokenFromHandler")] | ||
public static partial void UnableToValidateIdTokenFromHandler(this ILogger logger, string idToken); | ||
|
||
[LoggerMessage(57, LogLevel.Error, "The Validated Security Token must be of type JsonWebToken, but instead its type is: '{SecurityTokenType}'", EventName = "InvalidSecurityTokenTypeFromHandler")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(57, LogLevel.Error, "The Validated Security Token must be of type JsonWebToken, but instead its type is: '{SecurityTokenType}'", EventName = "InvalidSecurityTokenTypeFromHandler")] | |
[LoggerMessage(57, LogLevel.Error, "The Validated Security Token must be of type JsonWebToken, but instead its type is: '{SecurityTokenType}'.", EventName = "InvalidSecurityTokenTypeFromHandler")] |
} | ||
else | ||
{ | ||
tokenEndpointUser = ValidateToken(tokenEndpointResponse.IdToken, properties, validationParameters, out tokenEndpointJwt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tokenEndpointUser = ValidateToken(tokenEndpointResponse.IdToken, properties, validationParameters, out tokenEndpointJwt); | |
tokenEndpointUser = ValidateToken(tokenEndpointResponse.IdToken, properties, validationParameters, out tokenEndpointJwt); |
|
||
if (validatedToken is not JsonWebToken) | ||
{ | ||
Logger.InvalidSecurityTokenTypeFromHandler(validatedToken?.GetType().ToString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this log method to accept Type?
instead of string so we don't allocate the string unless it actually logs.
?? _configuration.SigningKeys; | ||
} | ||
|
||
var validationResult = await Options.TokenHandler.ValidateTokenAsync(idToken, validationParameters); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the async methods in identity not accept a cancellation token?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No
{ | ||
Options.ConfigurationManager.RequestRefresh(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The JwtBearer changes look good to me. It would be good to get others approval (for OIDC) before merge.
…kages to the latest patch release (7.0.3 & 2.15.2) (#51430) # Update the Microsoft.IdentityModel.* and Microsoft.Identity.Web.* packages to the latest patch release (7.0.3 & 2.15.2) Update the reference to the Microsoft.IdentityModel.* and Microsoft.Identity.Web.* packages so that we don't regress AAD authentication scenarios for web apps. ## Description We've hit an issue with AAD authentication in ASP.NET Core web apps, which was resulting in errors during login. This was due to an issue in the IdentityModel package, for which @halter73 has proposed a fix: AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet#2361 The Identity team has approved the fix and has released a new package to NuGet so that we can update our dependency and **avoid the regression in 8.0**. Please note, that this change will have to include the soure-build change as well: dotnet/source-build-externals#228 Fixes #51005 ## Customer Impact Customers who will try to use AAD authentication for their ASP.NET Core web applications in 8.0 will fail to login. ## Regression? - [x] Yes - [ ] No This was technically an existing bug, which was already in the IdentityModel package, however only after a recent change #49542 the issue has surfaced impacting 8.0 apps. ## Risk - [ ] High - [ ] Medium - [x] Low From our point of view this is a dependency update. And the dependency has taken only a targeted fix to avoid the bug, going through all the necessary validation on the AAD side. ## Verification - [x] Manual (required) - [ ] Automated ## Packaging changes reviewed? - [ ] Yes - [ ] No - [x] N/A ---- ## When servicing release/2.1 - [ ] Make necessary changes in eng/PatchConfig.props --------- Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: Stephen Halter <halter73@gmail.com>
Move aspnetcore to leverage JsonWebToken and JsonWebTokenHandler in .NET 8 preview 7
Updates the JwtBearer, WsFederation and OpenIdConnect authentication handlers to leverage more
performant and resilient token validation. Also enables developers to opt-out of this new improvement
if they choose too in .NET 8.
Description
ASP.NET, and then ASP.NET Core use Microsoft.IdentityModel to validate tokens. A more performant (30%), more resilient and async processing has been developed for three years and is widely used internally in Microsoft. It also offers defense in depth. This PR brings this improvement to ASP.NET Core in .NET 8 preview 7.
Fixes #49469 which also contains the API review
Customer Impact
Customers can expect a 30% performance in token validation, and associated COGS improvements. They also benefit from
resiliency by the usage of a last-known-good cache of the OpenIdConnect metadata.
By default ASP.NET Core uses the new improved token validation. There is no breaking change to the public API, but a behavioral
change in the TokenValidatedContext classes (for the three authentication handlers): the
SecurityToken
property (of abstract typeSecurityToken) used to be backed by the previous generation JwtSecurityToken, and is now backed by another derived class JsonWebToken. Developers can opt-out by setting a boolean. For details see https://aka.ms/aspnetcore8/security-token-changes
Regression?
Risk
The new classes have been extensively exercised internally in Microsoft for several years.
The PR doesn't bring regression, based on community feedback (see for instance here)
Verification
Packaging changes reviewed?
When servicing release/2.1