Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into pmaytak/1pjwt
Browse files Browse the repository at this point in the history
  • Loading branch information
pmaytak committed Jun 18, 2024
2 parents edbe8f2 + a2486af commit 464b592
Show file tree
Hide file tree
Showing 29 changed files with 195 additions and 105 deletions.
18 changes: 16 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
See the [releases](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/releases) for details on bug fixes and added features.


Pending Next Release
8.0.0-preview1
====
### Breaking changes:
- IdentityModel 8x no longer supports .net461, which has reached end of life and is no longer supported. See issue [#2544](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/2544) for details.
- Two IdentityModel extension dlls `Microsoft.IdentityModel.KeyVaultExtensions` and `Microsoft.IdentityModel.ManagedKeyVaultSecurityKey` were using ADAL, which is no longer supported . The affected packages have been removed, as the replacement is to use [Microsoft.Identity.Web](https://github.com/AzureAD/microsoft-identity-web/wiki/Certificates). See issue [#2454](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/2454) for details.
- `AppContext.SetSwitch` which were included in IdentityModel 7x, have been removed and are the default in IdentityModel 8x. The result is a more performant IdentityModel by default. See issue [#2629](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/2629) for details.

7.6.1
=====
### New Features:
- Add missing metadata parameters to OpenIdConnectConfiguration. See issue [#2498](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/2498) for details.

### Bug Fixes:
- Fix over-reporting of `IDX14100`. See issue [#2058](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/2058) and PR [#2618](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/2618) for details.
- `JwtRegisteredClaimNames` now contains previously missing Standard OpenIdConnect claims. See issue [#1598](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/1598) for details.

### Performance Improvements:
- Reduced allocations in `AadIssuerValidator` by not using `string.Replace` where appropriate. See issue [#2595](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/2595) and PR [#2597](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/2597) for more details.
- No longer for every string claim, calling DateTime.TryParse on each value, whether it is expected to be a DateTime or not. See issue [#2615](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/2615) for details.

7.6.0
=====
Expand Down
4 changes: 2 additions & 2 deletions build/targets.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<SrcTargets Condition="'$(LocalBuild)' != 'True'">net461;net462;net472;netstandard2.0;net6.0;net8.0</SrcTargets>
<SrcTargets Condition="'$(LocalBuild)' == 'True'">net461;netstandard2.0;net8.0</SrcTargets>
<SrcTargets Condition="'$(LocalBuild)' != 'True'">net462;net472;netstandard2.0;net6.0;net8.0</SrcTargets>
<SrcTargets Condition="'$(LocalBuild)' == 'True'">netstandard2.0;net8.0</SrcTargets>
<SrcTargets Condition="'$(TargetNet9)' == 'True'">$(SrcTargets);net9.0</SrcTargets>
<SrcStandardTargets>netstandard2.0</SrcStandardTargets>
</PropertyGroup>
Expand Down
4 changes: 2 additions & 2 deletions build/targetsTest.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<TestTargets Condition="'$(LocalBuild)' != 'True'">net461;net462;net472;netcoreapp2.1;net6.0;net8.0</TestTargets>
<TestTargets Condition="'$(LocalBuild)' == 'True'">net461;netcoreapp2.1;net8.0</TestTargets>
<TestTargets Condition="'$(LocalBuild)' != 'True'">net462;net472;netcoreapp2.1;net6.0;net8.0</TestTargets>
<TestTargets Condition="'$(LocalBuild)' == 'True'">netcoreapp2.1;net8.0</TestTargets>
<TestTargets Condition="'$(TargetNet9)' == 'True'">$(TestTargets);net9.0</TestTargets>
<TestOnlyCoreTargets>netcoreapp2.1</TestOnlyCoreTargets>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ public static class IdentityModelTelemetryUtil
/// Get the string that represents the client SKU.
/// </summary>
public static string ClientSku =>
#if NET461
"ID_NET461";
#elif NET462
#if NET462
"ID_NET462";
#elif NET472
"ID_NET472";
Expand Down
2 changes: 0 additions & 2 deletions src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,6 @@ public virtual SignatureProvider CreateForVerifying(SecurityKey key, string algo
return CreateSignatureProvider(key, algorithm, false, cacheProvider);
}

#if NET461 || NET462 || NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
/// <summary>
/// Creates a <see cref="HashAlgorithm"/> for a specific algorithm.
/// </summary>
Expand Down Expand Up @@ -354,7 +353,6 @@ public virtual HashAlgorithm CreateHashAlgorithm(HashAlgorithmName algorithm)

throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10640, LogHelper.MarkAsNonPII(algorithm))));
}
#endif

/// <summary>
/// Creates a <see cref="HashAlgorithm"/> for a specific algorithm.
Expand Down
34 changes: 6 additions & 28 deletions src/Microsoft.IdentityModel.Tokens/ECDsaAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,12 @@ internal ECDsaAdapter()
CreateECDsaFunction = CreateECDsaUsingECParams;
#elif NETSTANDARD2_0
// Although NETSTANDARD2_0 specifies that ECParameters are supported, we still need to call SupportsECParameters()
// as NET461 is listed as supporting NETSTANDARD2_0, but DOES NOT support ECParameters.
// as NET462 is listed as supporting NETSTANDARD2_0, but DOES NOT support ECParameters.
// See: https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.ecparameters?view=netstandard-2.0
if (SupportsECParameters())
CreateECDsaFunction = CreateECDsaUsingECParams;
else
CreateECDsaFunction = CreateECDsaUsingCNGKey;
if (SupportsECParameters()) CreateECDsaFunction = CreateECDsaUsingECParams;
else CreateECDsaFunction = CreateECDsaUsingCNGKey;
#else
CreateECDsaFunction = CreateECDsaUsingCNGKey;
CreateECDsaFunction = CreateECDsaUsingCNGKey;
#endif
}

Expand All @@ -51,7 +49,7 @@ internal ECDsa CreateECDsa(JsonWebKey jsonWebKey, bool usePrivateKey)
return CreateECDsaFunction(jsonWebKey, usePrivateKey);
}

#if NET461 || NET462 || NETSTANDARD2_0
#if NET462 || NETSTANDARD2_0
/// <summary>
/// Creates an ECDsa object using the <paramref name="jsonWebKey"/> and <paramref name="usePrivateKey"/>.
/// 'ECParameters' structure is available in .NET Framework 4.7+, .NET Standard 1.6+, and .NET Core 1.0+.
Expand Down Expand Up @@ -230,32 +228,12 @@ private static uint GetMagicValue(string curveId, bool willCreateSignatures)
return (uint)magicNumber;
}

/// <summary>
/// Tests if user's runtime platform supports operations using <see cref="CngKey"/>.
/// </summary>
/// <returns>True if operations using <see cref="CngKey"/> are supported on user's runtime platform, false otherwise.</returns>
[MethodImpl(MethodImplOptions.NoOptimization)]
private static bool SupportsCNGKey()
{
try
{
#pragma warning disable CA1416 // Validate platform compatibility
_ = CngKeyBlobFormat.EccPrivateBlob;
#pragma warning restore CA1416 // Validate platform compatibility
return true;
}
catch
{
return false;
}
}

#if NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
/// <summary>
/// Creates an ECDsa object using the <paramref name="jsonWebKey"/> and <paramref name="usePrivateKey"/>.
/// 'ECParameters' structure is available in .NET Framework 4.7+, .NET Standard 1.6+, and .NET Core 1.0+.
/// </summary>
private ECDsa CreateECDsaUsingECParams(JsonWebKey jsonWebKey, bool usePrivateKey)
private static ECDsa CreateECDsaUsingECParams(JsonWebKey jsonWebKey, bool usePrivateKey)
{
if (jsonWebKey == null)
throw LogHelper.LogArgumentNullException(nameof(jsonWebKey));
Expand Down
2 changes: 0 additions & 2 deletions src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
[assembly: SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.AuthenticatedEncryptionResult.AuthenticationTag")]
[assembly: SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.SymmetricSecurityKey.Key")]
[assembly: SuppressMessage("Usage", "CA2211:Non-constant fields should not be visible", Justification = "Breaking change", Scope = "member", Target = "~F:Microsoft.IdentityModel.Tokens.JsonWebKeySet.DefaultSkipUnresolvedJsonWebKeys")]
[assembly: SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "Used in net461", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.SupportedAlgorithms.IsSupportedRsaPss(Microsoft.IdentityModel.Tokens.SecurityKey)~System.Boolean")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Used as platform test", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.ECDsaAdapter.SupportsCNGKey~System.Boolean")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Used for try pattern", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.JsonWebKeyConverter.ConvertFromRSASecurityKey(Microsoft.IdentityModel.Tokens.RsaSecurityKey)~Microsoft.IdentityModel.Tokens.JsonWebKey")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Used for try pattern", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.JsonWebKeyConverter.TryConvertToECDsaSecurityKey(Microsoft.IdentityModel.Tokens.JsonWebKey,Microsoft.IdentityModel.Tokens.SecurityKey@)~System.Boolean")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Used for try pattern", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.JsonWebKeyConverter.TryConvertToSecurityKey(Microsoft.IdentityModel.Tokens.JsonWebKey,Microsoft.IdentityModel.Tokens.SecurityKey@)~System.Boolean")]
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.IdentityModel.Tokens/LogMessages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal static class LogMessages
{
#pragma warning disable 1591
// general
// public const string IDX10000 = "IDX10000:";
public const string IDX10000 = "IDX10000: The parameter '{0}' cannot be a 'null' or an empty object. ";

// properties, configuration
public const string IDX10101 = "IDX10101: MaximumTokenSizeInBytes must be greater than zero. value: '{0}'";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public bool VerifyData(byte[] input, object hash, byte[] signature)
return _rsa.VerifyData(input, hash, signature);
}

#if NET461 || NET462 || NET472 || NETSTANDARD2_0
#if NET462 || NET472 || NETSTANDARD2_0
/// <summary>
/// Verifies that a digital signature is valid by determining the hash value in the signature using the provided public key and comparing it to the hash value of the provided data.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.IdentityModel.Tokens/RsaSecurityKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public override bool HasPrivateKey
{
// imitate signing
byte[] hash = new byte[20];
#if NET461 || NET462 || NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
#if NET462 || NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
Rsa.SignData(hash, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
#else
if (Rsa is RSACryptoServiceProvider rsaCryptoServiceProvider)
Expand Down
2 changes: 0 additions & 2 deletions src/Microsoft.IdentityModel.Tokens/SupportedAlgorithms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ internal static class SupportedAlgorithms
SecurityAlgorithms.EcdhEsA256kw
};

#if NET461 || NET462 || NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
/// <summary>
/// Creating a Signature requires the use of a <see cref="HashAlgorithm"/>.
/// This method returns the <see cref="HashAlgorithmName"/>
Expand Down Expand Up @@ -148,7 +147,6 @@ internal static HashAlgorithmName GetHashAlgorithmName(string algorithm)

throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(algorithm), LogHelper.FormatInvariant(LogMessages.IDX10652, LogHelper.MarkAsNonPII(algorithm))));
}
#endif

/// <summary>
/// Creating a Signature requires the use of a <see cref="HashAlgorithm"/>.
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.IdentityModel.Tokens/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public static bool IsHttps(Uri uri)
{
return false;
}
#if NET461 || NET462
#if NET462
return uri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase); //Uri.UriSchemeHttps is internal in dnxcore
#else
return uri.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,27 @@ namespace Microsoft.IdentityModel.Tokens
/// </summary>
internal class IssuerValidationResult : ValidationResult
{
internal enum ValidationSource
{
NotValidated = 0,
IssuerIsConfigurationIssuer,
IssuerIsValidIssuer,
IssuerIsAmongValidIssuers
}

private Exception _exception;

/// <summary>
/// Creates an instance of <see cref="IssuerValidationResult"/>
/// </summary>
/// <paramref name="issuer"/> is the issuer that was validated successfully.
public IssuerValidationResult(string issuer)
/// <paramref name="source"/> is the <see cref="ValidationSource"/> indicating how this issuer was validated.
public IssuerValidationResult(string issuer, ValidationSource source = ValidationSource.NotValidated)
: base(ValidationFailureType.ValidationSucceeded)
{
Issuer = issuer;
IsValid = true;
Source = source;
}

/// <summary>
Expand All @@ -30,11 +40,13 @@ public IssuerValidationResult(string issuer)
/// <paramref name="issuer"/> is the issuer that was intended to be validated.
/// <paramref name="validationFailure"/> is the <see cref="ValidationFailureType"/> that occurred during validation.
/// <paramref name="exceptionDetail"/> is the <see cref="ExceptionDetail"/> that occurred during validation.
public IssuerValidationResult(string issuer, ValidationFailureType validationFailure, ExceptionDetail exceptionDetail)
/// <paramref name="source"/> is the <see cref="ValidationSource"/> indicating how this issuer was validated.
public IssuerValidationResult(string issuer, ValidationFailureType validationFailure, ExceptionDetail exceptionDetail, ValidationSource source = ValidationSource.NotValidated)
: base(validationFailure, exceptionDetail)
{
Issuer = issuer;
IsValid = false;
Source = source;
}

/// <summary>
Expand Down Expand Up @@ -65,5 +77,7 @@ public override Exception Exception
/// Gets the issuer that was validated or intended to be validated.
/// </summary>
public string Issuer { get; }

public ValidationSource Source { get; }
}
}
32 changes: 26 additions & 6 deletions src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,28 @@ internal static async Task<IssuerValidationResult> ValidateIssuerAsync(
}

if (validationParameters == null)
throw LogHelper.LogArgumentNullException(nameof(validationParameters));
return new IssuerValidationResult(
issuer,
ValidationFailureType.NullArgument,
new ExceptionDetail(
new MessageDetail(
LogMessages.IDX10000,
LogHelper.MarkAsNonPII(nameof(validationParameters))),
typeof(ArgumentNullException),
new StackFrame(true),
null));

if (securityToken == null)
throw LogHelper.LogArgumentNullException(nameof(securityToken));
return new IssuerValidationResult(
issuer,
ValidationFailureType.NullArgument,
new ExceptionDetail(
new MessageDetail(
LogMessages.IDX10000,
LogHelper.MarkAsNonPII(nameof(securityToken))),
typeof(ArgumentNullException),
new StackFrame(true),
null));

BaseConfiguration configuration = null;
if (validationParameters.ConfigurationManager != null)
Expand All @@ -234,7 +252,6 @@ internal static async Task<IssuerValidationResult> ValidateIssuerAsync(
new StackFrame(true)));
}

// TODO - we should distinguish if configuration, TVP.ValidIssuer or TVP.ValidIssuers was used to validate the issuer.
if (configuration != null)
{
if (string.Equals(configuration.Issuer, issuer))
Expand All @@ -245,13 +262,15 @@ internal static async Task<IssuerValidationResult> ValidateIssuerAsync(
if (LogHelper.IsEnabled(EventLogLevel.Informational))
LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer), callContext);

return new IssuerValidationResult(issuer);
return new IssuerValidationResult(issuer,
IssuerValidationResult.ValidationSource.IssuerIsConfigurationIssuer);
}
}

if (string.Equals(validationParameters.ValidIssuer, issuer))
{
return new IssuerValidationResult(issuer);
return new IssuerValidationResult(issuer,
IssuerValidationResult.ValidationSource.IssuerIsValidIssuer);
}

if (validationParameters.ValidIssuers != null)
Expand All @@ -271,7 +290,8 @@ internal static async Task<IssuerValidationResult> ValidateIssuerAsync(
if (LogHelper.IsEnabled(EventLogLevel.Informational))
LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer));

return new IssuerValidationResult(issuer);
return new IssuerValidationResult(issuer,
IssuerValidationResult.ValidationSource.IssuerIsAmongValidIssuers);
}
}
}
Expand Down
9 changes: 1 addition & 8 deletions src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,8 @@ public AsymmetricAlgorithm PrivateKey
{
if (!_privateKeyAvailabilityDetermined)
{
#if NET461 || NET462 || NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
_privateKey = RSACertificateExtensions.GetRSAPrivateKey(Certificate);
#else
_privateKey = Certificate.PrivateKey;
#endif

_privateKeyAvailabilityDetermined = true;
}
}
Expand All @@ -105,11 +102,7 @@ public AsymmetricAlgorithm PublicKey
{
if (_publicKey == null)
{
#if NET461 || NET462 || NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
_publicKey = RSACertificateExtensions.GetRSAPublicKey(Certificate);
#else
_publicKey = Certificate.PublicKey.Key;
#endif
}
}
}
Expand Down
Loading

0 comments on commit 464b592

Please sign in to comment.