diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 439ebd93b2..2f29ac340c 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -1,15 +1,25 @@
name: "CodeQL"
on:
- push:
- branches: [ "dev", "dev6x" ]
+ push:
+ paths-ignore:
+ - 'test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/**'
+ - 'test/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.Tests/**'
+ - '/src/Microsoft.IdentityModel.KeyVaultExtensions/**'
+ - '/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/**'
+ branches: [ "dev", "dev6x", "dev7x"]
pull_request:
+ paths-ignore:
+ - 'test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/**'
+ - 'test/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.Tests/**'
+ - '/src/Microsoft.IdentityModel.KeyVaultExtensions/**'
+ - '/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/**'
types:
- opened
- synchronize
- reopened
- ready_for_review
- branches: [ "dev", "dev6x" ]
+ branches: [ "dev", "dev6x", "dev7x"]
jobs:
analyze:
diff --git a/Wilson.sln b/Wilson.sln
index 9c671e6168..18274278e0 100644
--- a/Wilson.sln
+++ b/Wilson.sln
@@ -66,18 +66,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.Jso
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{EB14B99B-2255-45BC-BF14-E488DCD4A4BA}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{B961CF69-0DE6-4B9F-9473-9F669365BD62}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.KeyVaultExtensions.Tests", "test\Microsoft.IdentityModel.KeyVaultExtensions.Tests\Microsoft.IdentityModel.KeyVaultExtensions.Tests.csproj", "{987772FA-BA24-4EF4-9B58-3DA78FFD61DD}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.Tests", "test\Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.Tests\Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.Tests.csproj", "{97315A25-B694-4BD0-8DF5-C339884A6D26}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.KeyVaultExtensions", "src\Microsoft.IdentityModel.KeyVaultExtensions\Microsoft.IdentityModel.KeyVaultExtensions.csproj", "{F5636C24-D6D5-4F6A-8A21-7C78FC1FC6C6}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.TestExtensions", "src\Microsoft.IdentityModel.TestExtensions\Microsoft.IdentityModel.TestExtensions.csproj", "{AF787AA8-DE6E-4B74-816E-E8F3203A2FA0}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.ManagedKeyVaultSecurityKey", "src\Microsoft.IdentityModel.ManagedKeyVaultSecurityKey\Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.csproj", "{8DFF1DEA-F01F-4CE4-9471-5D2CEFB7E59F}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.Protocols.SignedHttpRequest", "src\Microsoft.IdentityModel.Protocols.SignedHttpRequest\Microsoft.IdentityModel.Protocols.SignedHttpRequest.csproj", "{C768FBB5-DE0D-4970-918C-96B37485E34C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests", "test\Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests\Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests.csproj", "{15944563-F7DA-4150-B5F1-6144EBF2CE23}"
@@ -85,6 +75,8 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4655DBB4-70C6-475D-8971-FE6619B85F70}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
+ buildPack.bat = buildPack.bat
+ buildTestPack.bat = buildTestPack.bat
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.Validators", "src\Microsoft.IdentityModel.Validators\Microsoft.IdentityModel.Validators.csproj", "{DA585910-0E6C-45A5-AABD-30917130FD63}"
@@ -198,26 +190,10 @@ Global
{DBF58792-25DF-4B6E-866C-77A0BC5AB81B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DBF58792-25DF-4B6E-866C-77A0BC5AB81B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DBF58792-25DF-4B6E-866C-77A0BC5AB81B}.Release|Any CPU.Build.0 = Release|Any CPU
- {987772FA-BA24-4EF4-9B58-3DA78FFD61DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {987772FA-BA24-4EF4-9B58-3DA78FFD61DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {987772FA-BA24-4EF4-9B58-3DA78FFD61DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {987772FA-BA24-4EF4-9B58-3DA78FFD61DD}.Release|Any CPU.Build.0 = Release|Any CPU
- {97315A25-B694-4BD0-8DF5-C339884A6D26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {97315A25-B694-4BD0-8DF5-C339884A6D26}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {97315A25-B694-4BD0-8DF5-C339884A6D26}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {97315A25-B694-4BD0-8DF5-C339884A6D26}.Release|Any CPU.Build.0 = Release|Any CPU
- {F5636C24-D6D5-4F6A-8A21-7C78FC1FC6C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F5636C24-D6D5-4F6A-8A21-7C78FC1FC6C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F5636C24-D6D5-4F6A-8A21-7C78FC1FC6C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F5636C24-D6D5-4F6A-8A21-7C78FC1FC6C6}.Release|Any CPU.Build.0 = Release|Any CPU
{AF787AA8-DE6E-4B74-816E-E8F3203A2FA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF787AA8-DE6E-4B74-816E-E8F3203A2FA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF787AA8-DE6E-4B74-816E-E8F3203A2FA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF787AA8-DE6E-4B74-816E-E8F3203A2FA0}.Release|Any CPU.Build.0 = Release|Any CPU
- {8DFF1DEA-F01F-4CE4-9471-5D2CEFB7E59F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8DFF1DEA-F01F-4CE4-9471-5D2CEFB7E59F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8DFF1DEA-F01F-4CE4-9471-5D2CEFB7E59F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8DFF1DEA-F01F-4CE4-9471-5D2CEFB7E59F}.Release|Any CPU.Build.0 = Release|Any CPU
{C768FBB5-DE0D-4970-918C-96B37485E34C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C768FBB5-DE0D-4970-918C-96B37485E34C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C768FBB5-DE0D-4970-918C-96B37485E34C}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -287,12 +263,7 @@ Global
{E4E6D0ED-12CB-4C01-A4C1-4F60D10E2304} = {BD2706C5-6C57-484D-89C8-A0CF5F8E3D19}
{DBF58792-25DF-4B6E-866C-77A0BC5AB81B} = {BD2706C5-6C57-484D-89C8-A0CF5F8E3D19}
{EB14B99B-2255-45BC-BF14-E488DCD4A4BA} = {BD2706C5-6C57-484D-89C8-A0CF5F8E3D19}
- {B961CF69-0DE6-4B9F-9473-9F669365BD62} = {8905D2E3-4499-4A86-BF3E-F098F228DD59}
- {987772FA-BA24-4EF4-9B58-3DA78FFD61DD} = {B961CF69-0DE6-4B9F-9473-9F669365BD62}
- {97315A25-B694-4BD0-8DF5-C339884A6D26} = {B961CF69-0DE6-4B9F-9473-9F669365BD62}
- {F5636C24-D6D5-4F6A-8A21-7C78FC1FC6C6} = {EB14B99B-2255-45BC-BF14-E488DCD4A4BA}
{AF787AA8-DE6E-4B74-816E-E8F3203A2FA0} = {EB14B99B-2255-45BC-BF14-E488DCD4A4BA}
- {8DFF1DEA-F01F-4CE4-9471-5D2CEFB7E59F} = {EB14B99B-2255-45BC-BF14-E488DCD4A4BA}
{C768FBB5-DE0D-4970-918C-96B37485E34C} = {BD2706C5-6C57-484D-89C8-A0CF5F8E3D19}
{15944563-F7DA-4150-B5F1-6144EBF2CE23} = {8905D2E3-4499-4A86-BF3E-F098F228DD59}
{DA585910-0E6C-45A5-AABD-30917130FD63} = {BD2706C5-6C57-484D-89C8-A0CF5F8E3D19}
diff --git a/build/common.props b/build/common.props
index 0fbddb3d63..efd7e90e2f 100644
--- a/build/common.props
+++ b/build/common.props
@@ -32,7 +32,7 @@
- 7.6.1
+ 8.0.0
preview-$([System.DateTime]::Now.AddYears(-2019).Year)$([System.DateTime]::Now.ToString("MMddHHmmss"))
@@ -46,8 +46,8 @@
- true
- 7.0.0
+ false
+ 8.0.0
diff --git a/build/dependencies.props b/build/dependencies.props
index 23e1b91065..8203da572c 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -2,8 +2,6 @@
2.1.1
- 3.0.5
- 1.0.3
4.5.0
1.0.0
2.0.3
diff --git a/buildConfiguration.xml b/buildConfiguration.xml
index 06e064dafa..0abda703bf 100644
--- a/buildConfiguration.xml
+++ b/buildConfiguration.xml
@@ -14,8 +14,6 @@
-
-
@@ -33,8 +31,6 @@
-
-
diff --git a/buildPack.bat b/buildPack.bat
index 7e782b647f..6a4c89623c 100644
--- a/buildPack.bat
+++ b/buildPack.bat
@@ -1,2 +1,3 @@
+dotnet clean Product.proj > clean.log
dotnet build /r Product.proj
dotnet pack --no-restore -o artifacts --no-build Product.proj
diff --git a/buildTestPack.bat b/buildTestPack.bat
index 40e59fda52..b5dba1b86f 100644
--- a/buildTestPack.bat
+++ b/buildTestPack.bat
@@ -1,3 +1,4 @@
+dotnet clean Product.proj > clean.log
dotnet build /r Product.proj
dotnet test --no-restore --no-build Product.proj
dotnet pack --no-restore -o artifacts --no-build Product.proj
diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.ValidateToken.cs b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.ValidateToken.cs
new file mode 100644
index 0000000000..3242311e9a
--- /dev/null
+++ b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.ValidateToken.cs
@@ -0,0 +1,771 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.IdentityModel.Abstractions;
+using Microsoft.IdentityModel.Logging;
+using Microsoft.IdentityModel.Tokens;
+using TokenLogMessages = Microsoft.IdentityModel.Tokens.LogMessages;
+
+namespace Microsoft.IdentityModel.JsonWebTokens
+{
+ ///
+ /// A designed for creating and validating Json Web Tokens.
+ /// See: https://datatracker.ietf.org/doc/html/rfc7519 and http://www.rfc-editor.org/info/rfc7515.
+ ///
+ public partial class JsonWebTokenHandler : TokenHandler
+ {
+ ///
+ /// Returns a value that indicates if this handler can validate a .
+ ///
+ /// 'true', indicating this instance can validate a .
+ public virtual bool CanValidateToken
+ {
+ get { return true; }
+ }
+
+ internal async ValueTask ValidateJWEAsync(
+ JsonWebToken jwtToken,
+ TokenValidationParameters validationParameters,
+ BaseConfiguration configuration)
+ {
+ try
+ {
+ TokenValidationResult tokenValidationResult = ReadToken(DecryptToken(jwtToken, validationParameters), validationParameters);
+ if (!tokenValidationResult.IsValid)
+ return tokenValidationResult;
+
+
+ tokenValidationResult = await ValidateJWSAsync(
+ tokenValidationResult.SecurityToken as JsonWebToken,
+ validationParameters,
+ configuration).ConfigureAwait(false);
+
+ if (!tokenValidationResult.IsValid)
+ return tokenValidationResult;
+
+ jwtToken.InnerToken = tokenValidationResult.SecurityToken as JsonWebToken;
+ jwtToken.Payload = (tokenValidationResult.SecurityToken as JsonWebToken).Payload;
+ return new TokenValidationResult
+ {
+ SecurityToken = jwtToken,
+ ClaimsIdentityNoLocking = tokenValidationResult.ClaimsIdentityNoLocking,
+ IsValid = true,
+ TokenType = tokenValidationResult.TokenType
+ };
+ }
+#pragma warning disable CA1031 // Do not catch general exception types
+ catch (Exception ex)
+#pragma warning restore CA1031 // Do not catch general exception types
+ {
+ return new TokenValidationResult
+ {
+ Exception = ex,
+ IsValid = false,
+ TokenOnFailedValidation = validationParameters.IncludeTokenOnFailedValidation ? jwtToken : null
+ };
+ }
+ }
+
+ internal async ValueTask ValidateJWEAsync(
+ JsonWebToken jwtToken,
+ TokenValidationParameters validationParameters,
+ CallContext callContext,
+ CancellationToken cancellationToken)
+ {
+ try
+ {
+ TokenValidationResult tokenValidationResult = ReadToken(DecryptToken(jwtToken, validationParameters), validationParameters);
+ if (!tokenValidationResult.IsValid)
+ return tokenValidationResult;
+
+ tokenValidationResult = await ValidateJWSAsync(
+ tokenValidationResult.SecurityToken as JsonWebToken,
+ validationParameters,
+ callContext,
+ cancellationToken).ConfigureAwait(false);
+
+ if (!tokenValidationResult.IsValid)
+ return tokenValidationResult;
+
+ jwtToken.InnerToken = tokenValidationResult.SecurityToken as JsonWebToken;
+ jwtToken.Payload = (tokenValidationResult.SecurityToken as JsonWebToken).Payload;
+ return new TokenValidationResult
+ {
+ SecurityToken = jwtToken,
+ ClaimsIdentityNoLocking = tokenValidationResult.ClaimsIdentityNoLocking,
+ IsValid = true,
+ TokenType = tokenValidationResult.TokenType
+ };
+ }
+#pragma warning disable CA1031 // Do not catch general exception types
+ catch (Exception ex)
+#pragma warning restore CA1031 // Do not catch general exception types
+ {
+ return new TokenValidationResult
+ {
+ Exception = ex,
+ IsValid = false,
+ TokenOnFailedValidation = validationParameters.IncludeTokenOnFailedValidation ? jwtToken : null
+ };
+ }
+ }
+
+ internal async ValueTask ValidateJWSAsync(
+ JsonWebToken jsonWebToken,
+ TokenValidationParameters validationParameters,
+ BaseConfiguration configuration)
+ {
+ try
+ {
+ TokenValidationResult tokenValidationResult;
+ if (validationParameters.TransformBeforeSignatureValidation != null)
+ jsonWebToken = validationParameters.TransformBeforeSignatureValidation(jsonWebToken, validationParameters) as JsonWebToken;
+
+ if (validationParameters.SignatureValidator != null || validationParameters.SignatureValidatorUsingConfiguration != null)
+ {
+ var validatedToken = ValidateSignatureUsingDelegates(jsonWebToken, validationParameters);
+ tokenValidationResult = await ValidateTokenPayloadAsync(
+ validatedToken,
+ validationParameters,
+ configuration).ConfigureAwait(false);
+
+ Validators.ValidateIssuerSecurityKey(validatedToken.SigningKey, validatedToken, validationParameters);
+ }
+ else
+ {
+ if (validationParameters.ValidateSignatureLast)
+ {
+ tokenValidationResult = await ValidateTokenPayloadAsync(
+ jsonWebToken,
+ validationParameters,
+ configuration).ConfigureAwait(false);
+
+ if (tokenValidationResult.IsValid)
+ tokenValidationResult.SecurityToken = ValidateSignatureAndIssuerSecurityKey(jsonWebToken, validationParameters, configuration);
+ }
+ else
+ {
+ var validatedToken = ValidateSignatureAndIssuerSecurityKey(jsonWebToken, validationParameters, configuration);
+ tokenValidationResult = await ValidateTokenPayloadAsync(
+ validatedToken,
+ validationParameters,
+ configuration).ConfigureAwait(false);
+ }
+ }
+
+ return tokenValidationResult;
+ }
+#pragma warning disable CA1031 // Do not catch general exception types
+ catch (Exception ex)
+#pragma warning restore CA1031 // Do not catch general exception types
+ {
+ return new TokenValidationResult
+ {
+ Exception = ex,
+ IsValid = false,
+ TokenOnFailedValidation = validationParameters.IncludeTokenOnFailedValidation ? jsonWebToken : null
+ };
+ }
+ }
+
+ internal async ValueTask ValidateJWSAsync(
+ JsonWebToken jsonWebToken,
+ TokenValidationParameters validationParameters,
+ CallContext callContext,
+ CancellationToken cancellationToken)
+ {
+ try
+ {
+ BaseConfiguration currentConfiguration = null;
+ if (validationParameters.ConfigurationManager != null)
+ {
+ try
+ {
+ currentConfiguration = await validationParameters.ConfigurationManager.GetBaseConfigurationAsync(CancellationToken.None).ConfigureAwait(false);
+ }
+#pragma warning disable CA1031 // Do not catch general exception types
+ catch (Exception ex)
+#pragma warning restore CA1031 // Do not catch general exception types
+ {
+ // The exception is not re-thrown as the TokenValidationParameters may have the issuer and signing key set
+ // directly on them, allowing the library to continue with token validation.
+ if (LogHelper.IsEnabled(EventLogLevel.Warning))
+ LogHelper.LogWarning(LogHelper.FormatInvariant(TokenLogMessages.IDX10261, validationParameters.ConfigurationManager.MetadataAddress, ex.ToString()));
+ }
+ }
+
+ TokenValidationResult tokenValidationResult;
+ if (validationParameters.TransformBeforeSignatureValidation != null)
+ jsonWebToken = validationParameters.TransformBeforeSignatureValidation(jsonWebToken, validationParameters) as JsonWebToken;
+
+ if (validationParameters.SignatureValidator != null || validationParameters.SignatureValidatorUsingConfiguration != null)
+ {
+ var validatedToken = ValidateSignatureUsingDelegates(jsonWebToken, validationParameters);
+ tokenValidationResult = await ValidateTokenPayloadAsync(
+ validatedToken,
+ validationParameters,
+ callContext,
+ cancellationToken).ConfigureAwait(false);
+
+ Validators.ValidateIssuerSecurityKey(validatedToken.SigningKey, validatedToken, validationParameters);
+ }
+ else
+ {
+ if (validationParameters.ValidateSignatureLast)
+ {
+ tokenValidationResult = await ValidateTokenPayloadAsync(
+ jsonWebToken,
+ validationParameters,
+ callContext,
+ cancellationToken).ConfigureAwait(false);
+
+ if (tokenValidationResult.IsValid)
+ tokenValidationResult.SecurityToken = ValidateSignatureAndIssuerSecurityKey(jsonWebToken, validationParameters, currentConfiguration);
+ }
+ else
+ {
+ var validatedToken = ValidateSignatureAndIssuerSecurityKey(jsonWebToken, validationParameters, currentConfiguration);
+ tokenValidationResult = await ValidateTokenPayloadAsync(
+ validatedToken,
+ validationParameters,
+ callContext,
+ cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ return tokenValidationResult;
+ }
+#pragma warning disable CA1031 // Do not catch general exception types
+ catch (Exception ex)
+#pragma warning restore CA1031 // Do not catch general exception types
+ {
+ return new TokenValidationResult
+ {
+ Exception = ex,
+ IsValid = false,
+ TokenOnFailedValidation = validationParameters.IncludeTokenOnFailedValidation ? jsonWebToken : null
+ };
+ }
+ }
+
+ private static JsonWebToken ValidateSignatureAndIssuerSecurityKey(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
+ {
+ JsonWebToken validatedToken = ValidateSignature(jsonWebToken, validationParameters, configuration);
+ Validators.ValidateIssuerSecurityKey(validatedToken.SigningKey, jsonWebToken, validationParameters, configuration);
+ return validatedToken;
+ }
+
+ ///
+ /// Validates the JWT signature.
+ ///
+ private static JsonWebToken ValidateSignature(JsonWebToken jwtToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
+ {
+ bool kidMatched = false;
+ IEnumerable keys = null;
+
+ if (!jwtToken.IsSigned)
+ {
+ if (validationParameters.RequireSignedTokens)
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10504, jwtToken)));
+ else
+ return jwtToken;
+ }
+
+ if (validationParameters.IssuerSigningKeyResolverUsingConfiguration != null)
+ {
+ keys = validationParameters.IssuerSigningKeyResolverUsingConfiguration(jwtToken.EncodedToken, jwtToken, jwtToken.Kid, validationParameters, configuration);
+ }
+ else if (validationParameters.IssuerSigningKeyResolver != null)
+ {
+ keys = validationParameters.IssuerSigningKeyResolver(jwtToken.EncodedToken, jwtToken, jwtToken.Kid, validationParameters);
+ }
+ else
+ {
+ var key = JwtTokenUtilities.ResolveTokenSigningKey(jwtToken.Kid, jwtToken.X5t, validationParameters, configuration);
+ if (key != null)
+ {
+ kidMatched = true;
+ keys = [key];
+ }
+ }
+
+ if (validationParameters.TryAllIssuerSigningKeys && keys.IsNullOrEmpty())
+ {
+ // control gets here if:
+ // 1. User specified delegate: IssuerSigningKeyResolver returned null
+ // 2. ResolveIssuerSigningKey returned null
+ // Try all the keys. This is the degenerate case, not concerned about perf.
+ keys = TokenUtilities.GetAllSigningKeys(configuration, validationParameters);
+ }
+
+ // keep track of exceptions thrown, keys that were tried
+ StringBuilder exceptionStrings = null;
+ StringBuilder keysAttempted = null;
+ var kidExists = !string.IsNullOrEmpty(jwtToken.Kid);
+
+ if (keys != null)
+ {
+ foreach (var key in keys)
+ {
+#pragma warning disable CA1031 // Do not catch general exception types
+ try
+ {
+ if (ValidateSignature(jwtToken, key, validationParameters))
+ {
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(TokenLogMessages.IDX10242, jwtToken);
+
+ jwtToken.SigningKey = key;
+ return jwtToken;
+ }
+ }
+ catch (Exception ex)
+ {
+ (exceptionStrings ??= new StringBuilder()).AppendLine(ex.ToString());
+ }
+#pragma warning restore CA1031 // Do not catch general exception types
+
+ if (key != null)
+ {
+ (keysAttempted ??= new StringBuilder()).Append(key.ToString()).Append(" , KeyId: ").AppendLine(key.KeyId);
+ if (kidExists && !kidMatched && key.KeyId != null)
+ kidMatched = jwtToken.Kid.Equals(key.KeyId, key is X509SecurityKey ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
+ }
+ }
+ }
+
+ // Get information on where keys used during token validation came from for debugging purposes.
+ var keysInTokenValidationParameters = TokenUtilities.GetAllSigningKeys(validationParameters: validationParameters);
+
+ var keysInConfiguration = TokenUtilities.GetAllSigningKeys(configuration);
+ var numKeysInTokenValidationParameters = keysInTokenValidationParameters.Count();
+ var numKeysInConfiguration = keysInConfiguration.Count();
+
+ if (kidExists)
+ {
+ if (kidMatched)
+ {
+ JsonWebToken localJwtToken = jwtToken; // avoid closure on non-exceptional path
+ var isKidInTVP = keysInTokenValidationParameters.Any(x => x.KeyId.Equals(localJwtToken.Kid));
+ var keyLocation = isKidInTVP ? "TokenValidationParameters" : "Configuration";
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10511,
+ LogHelper.MarkAsNonPII((object)keysAttempted ?? ""),
+ LogHelper.MarkAsNonPII(numKeysInTokenValidationParameters),
+ LogHelper.MarkAsNonPII(numKeysInConfiguration),
+ LogHelper.MarkAsNonPII(keyLocation),
+ LogHelper.MarkAsNonPII(jwtToken.Kid),
+ (object)exceptionStrings ?? "",
+ jwtToken)));
+ }
+
+ if (!validationParameters.ValidateSignatureLast)
+ {
+ InternalValidators.ValidateAfterSignatureFailed(
+ jwtToken,
+ jwtToken.ValidFromNullable,
+ jwtToken.ValidToNullable,
+ jwtToken.Audiences,
+ validationParameters,
+ configuration);
+ }
+ }
+
+ if (keysAttempted is not null)
+ {
+ if (kidExists)
+ {
+ throw LogHelper.LogExceptionMessage(new SecurityTokenSignatureKeyNotFoundException(LogHelper.FormatInvariant(TokenLogMessages.IDX10503,
+ LogHelper.MarkAsNonPII(jwtToken.Kid),
+ LogHelper.MarkAsNonPII((object)keysAttempted ?? ""),
+ LogHelper.MarkAsNonPII(numKeysInTokenValidationParameters),
+ LogHelper.MarkAsNonPII(numKeysInConfiguration),
+ (object)exceptionStrings ?? "",
+ jwtToken)));
+ }
+ else
+ {
+ throw LogHelper.LogExceptionMessage(new SecurityTokenSignatureKeyNotFoundException(LogHelper.FormatInvariant(TokenLogMessages.IDX10517,
+ LogHelper.MarkAsNonPII((object)keysAttempted ?? ""),
+ LogHelper.MarkAsNonPII(numKeysInTokenValidationParameters),
+ LogHelper.MarkAsNonPII(numKeysInConfiguration),
+ (object)exceptionStrings ?? "",
+ jwtToken)));
+ }
+ }
+
+ throw LogHelper.LogExceptionMessage(new SecurityTokenSignatureKeyNotFoundException(TokenLogMessages.IDX10500));
+ }
+
+ internal static bool IsSignatureValid(byte[] signatureBytes, int signatureBytesLength, SignatureProvider signatureProvider, byte[] dataToVerify, int dataToVerifyLength)
+ {
+ if (signatureProvider is SymmetricSignatureProvider)
+ {
+ return signatureProvider.Verify(dataToVerify, 0, dataToVerifyLength, signatureBytes, 0, signatureBytesLength);
+ }
+ else
+ {
+ if (signatureBytes.Length == signatureBytesLength)
+ {
+ return signatureProvider.Verify(dataToVerify, 0, dataToVerifyLength, signatureBytes, 0, signatureBytesLength);
+ }
+ else
+ {
+ byte[] sigBytes = new byte[signatureBytesLength];
+ Array.Copy(signatureBytes, 0, sigBytes, 0, signatureBytesLength);
+ return signatureProvider.Verify(dataToVerify, 0, dataToVerifyLength, sigBytes, 0, signatureBytesLength);
+ }
+ }
+ }
+
+ internal static bool ValidateSignature(byte[] bytes, int len, string stringWithSignature, int signatureStartIndex, SignatureProvider signatureProvider)
+ {
+ return Base64UrlEncoding.Decode(
+ stringWithSignature,
+ signatureStartIndex + 1,
+ stringWithSignature.Length - signatureStartIndex - 1,
+ signatureProvider,
+ bytes,
+ len,
+ IsSignatureValid);
+ }
+
+ internal static bool ValidateSignature(JsonWebToken jsonWebToken, SecurityKey key, TokenValidationParameters validationParameters)
+ {
+ var cryptoProviderFactory = validationParameters.CryptoProviderFactory ?? key.CryptoProviderFactory;
+ if (!cryptoProviderFactory.IsSupportedAlgorithm(jsonWebToken.Alg, key))
+ {
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX14000, LogHelper.MarkAsNonPII(jsonWebToken.Alg), key);
+
+ return false;
+ }
+
+ Validators.ValidateAlgorithm(jsonWebToken.Alg, key, jsonWebToken, validationParameters);
+ var signatureProvider = cryptoProviderFactory.CreateForVerifying(key, jsonWebToken.Alg);
+ try
+ {
+ if (signatureProvider == null)
+ throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(TokenLogMessages.IDX10636, key == null ? "Null" : key.ToString(), LogHelper.MarkAsNonPII(jsonWebToken.Alg))));
+
+ return EncodingUtils.PerformEncodingDependentOperation(
+ jsonWebToken.EncodedToken,
+ 0,
+ jsonWebToken.Dot2,
+ Encoding.UTF8,
+ jsonWebToken.EncodedToken,
+ jsonWebToken.Dot2,
+ signatureProvider,
+ ValidateSignature);
+ }
+ finally
+ {
+ cryptoProviderFactory.ReleaseSignatureProvider(signatureProvider);
+ }
+ }
+
+ private static JsonWebToken ValidateSignatureUsingDelegates(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters)
+ {
+ if (validationParameters.SignatureValidatorUsingConfiguration != null)
+ {
+ // TODO - get configuration from validationParameters
+ BaseConfiguration configuration = null;
+ var validatedToken = validationParameters.SignatureValidatorUsingConfiguration(jsonWebToken.EncodedToken, validationParameters, configuration);
+ if (validatedToken == null)
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10505, jsonWebToken)));
+
+ if (!(validatedToken is JsonWebToken validatedJsonWebToken))
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10506, LogHelper.MarkAsNonPII(typeof(JsonWebToken)), LogHelper.MarkAsNonPII(validatedToken.GetType()), jsonWebToken)));
+
+ return validatedJsonWebToken;
+ }
+ else if (validationParameters.SignatureValidator != null)
+ {
+ var validatedToken = validationParameters.SignatureValidator(jsonWebToken.EncodedToken, validationParameters);
+ if (validatedToken == null)
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10505, jsonWebToken)));
+
+ if (!(validatedToken is JsonWebToken validatedJsonWebToken))
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10506, LogHelper.MarkAsNonPII(typeof(JsonWebToken)), LogHelper.MarkAsNonPII(validatedToken.GetType()), jsonWebToken)));
+
+ return validatedJsonWebToken;
+ }
+
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10505, jsonWebToken)));
+ }
+
+ ///
+ /// Validates a JWS or a JWE.
+ ///
+ /// A 'JSON Web Token' (JWT) in JWS or JWE Compact Serialization Format.
+ /// A required for validation.
+ /// A
+ [Obsolete("`JsonWebTokens.ValidateToken(string, TokenValidationParameters)` has been deprecated and will be removed in a future release. Use `JsonWebTokens.ValidateTokenAsync(string, TokenValidationParameters)` instead. For more information, see https://aka.ms/IdentityModel/7-breaking-changes", false)]
+ public virtual TokenValidationResult ValidateToken(string token, TokenValidationParameters validationParameters)
+ {
+ return ValidateTokenAsync(token, validationParameters).ConfigureAwait(false).GetAwaiter().GetResult();
+ }
+
+ ///
+ /// Validates a token.
+ /// On a validation failure, no exception will be thrown; instead, the exception will be set in the returned TokenValidationResult.Exception property.
+ /// Callers should always check the TokenValidationResult.IsValid property to verify the validity of the result.
+ ///
+ /// The token to be validated.
+ /// A required for validation.
+ /// A
+ ///
+ /// TokenValidationResult.Exception will be set to one of the following exceptions if the is invalid.
+ /// if is null or empty.
+ /// if is null.
+ /// 'token.Length' is greater than .
+ /// if is not a valid ,
+ /// if the validationParameters.TokenReader delegate is not able to parse/read the token as a valid ,
+ ///
+ public override async Task ValidateTokenAsync(string token, TokenValidationParameters validationParameters)
+ {
+ if (string.IsNullOrEmpty(token))
+ return new TokenValidationResult { Exception = LogHelper.LogArgumentNullException(nameof(token)), IsValid = false };
+
+ if (validationParameters == null)
+ return new TokenValidationResult { Exception = LogHelper.LogArgumentNullException(nameof(validationParameters)), IsValid = false };
+
+ if (token.Length > MaximumTokenSizeInBytes)
+ return new TokenValidationResult { Exception = LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(TokenLogMessages.IDX10209, LogHelper.MarkAsNonPII(token.Length), LogHelper.MarkAsNonPII(MaximumTokenSizeInBytes)))), IsValid = false };
+
+ try
+ {
+ TokenValidationResult result = ReadToken(token, validationParameters);
+ if (result.IsValid)
+ return await ValidateTokenAsync(result.SecurityToken, validationParameters).ConfigureAwait(false);
+
+ return result;
+ }
+ catch (Exception ex)
+ {
+ return new TokenValidationResult
+ {
+ Exception = ex,
+ IsValid = false
+ };
+ }
+ }
+
+ ///
+ public override async Task ValidateTokenAsync(SecurityToken token, TokenValidationParameters validationParameters)
+ {
+ if (token == null)
+ throw LogHelper.LogArgumentNullException(nameof(token));
+
+ if (validationParameters == null)
+ return new TokenValidationResult { Exception = LogHelper.LogArgumentNullException(nameof(validationParameters)), IsValid = false };
+
+ var jwt = token as JsonWebToken;
+ if (jwt == null)
+ return new TokenValidationResult { Exception = LogHelper.LogArgumentException(nameof(token), $"{nameof(token)} must be a {nameof(JsonWebToken)}."), IsValid = false };
+
+ try
+ {
+ return await ValidateTokenAsync(jwt, validationParameters).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ return new TokenValidationResult
+ {
+ Exception = ex,
+ IsValid = false
+ };
+ }
+ }
+
+ ///
+ /// Internal method for token validation, responsible for:
+ /// (1) Obtaining a configuration from the .
+ /// (2) Revalidating using the Last Known Good Configuration (if present), and obtaining a refreshed configuration (if necessary) and revalidating using it.
+ ///
+ /// The JWT token
+ /// The to be used for validation.
+ ///
+ internal async ValueTask ValidateTokenAsync(
+ JsonWebToken jsonWebToken,
+ TokenValidationParameters validationParameters)
+ {
+ BaseConfiguration currentConfiguration = null;
+ if (validationParameters.ConfigurationManager != null)
+ {
+ try
+ {
+ currentConfiguration = await validationParameters.ConfigurationManager.GetBaseConfigurationAsync(CancellationToken.None).ConfigureAwait(false);
+ }
+#pragma warning disable CA1031 // Do not catch general exception types
+ catch (Exception ex)
+#pragma warning restore CA1031 // Do not catch general exception types
+ {
+ // The exception is not re-thrown as the TokenValidationParameters may have the issuer and signing key set
+ // directly on them, allowing the library to continue with token validation.
+ if (LogHelper.IsEnabled(EventLogLevel.Warning))
+ LogHelper.LogWarning(LogHelper.FormatInvariant(TokenLogMessages.IDX10261, validationParameters.ConfigurationManager.MetadataAddress, ex.ToString()));
+ }
+ }
+
+ TokenValidationResult tokenValidationResult = jsonWebToken.IsEncrypted ?
+ await ValidateJWEAsync(jsonWebToken, validationParameters, currentConfiguration).ConfigureAwait(false) :
+ await ValidateJWSAsync(jsonWebToken, validationParameters, currentConfiguration).ConfigureAwait(false);
+
+ if (validationParameters.ConfigurationManager != null)
+ {
+ if (tokenValidationResult.IsValid)
+ {
+ // Set current configuration as LKG if it exists.
+ if (currentConfiguration != null)
+ validationParameters.ConfigurationManager.LastKnownGoodConfiguration = currentConfiguration;
+
+ return tokenValidationResult;
+ }
+ else if (TokenUtilities.IsRecoverableException(tokenValidationResult.Exception))
+ {
+ // If we were still unable to validate, attempt to refresh the configuration and validate using it
+ // but ONLY if the currentConfiguration is not null. We want to avoid refreshing the configuration on
+ // retrieval error as this case should have already been hit before. This refresh handles the case
+ // where a new valid configuration was somehow published during validation time.
+ if (currentConfiguration != null)
+ {
+ validationParameters.ConfigurationManager.RequestRefresh();
+ validationParameters.RefreshBeforeValidation = true;
+ var lastConfig = currentConfiguration;
+ currentConfiguration = await validationParameters.ConfigurationManager.GetBaseConfigurationAsync(CancellationToken.None).ConfigureAwait(false);
+
+ // Only try to re-validate using the newly obtained config if it doesn't reference equal the previously used configuration.
+ if (lastConfig != currentConfiguration)
+ {
+ tokenValidationResult = jsonWebToken.IsEncrypted ?
+ await ValidateJWEAsync(jsonWebToken, validationParameters, currentConfiguration).ConfigureAwait(false) :
+ await ValidateJWSAsync(jsonWebToken, validationParameters, currentConfiguration).ConfigureAwait(false);
+
+ if (tokenValidationResult.IsValid)
+ {
+ validationParameters.ConfigurationManager.LastKnownGoodConfiguration = currentConfiguration;
+ return tokenValidationResult;
+ }
+ }
+ }
+
+ if (validationParameters.ConfigurationManager.UseLastKnownGoodConfiguration)
+ {
+ validationParameters.RefreshBeforeValidation = false;
+ validationParameters.ValidateWithLKG = true;
+ var recoverableException = tokenValidationResult.Exception;
+
+ foreach (BaseConfiguration lkgConfiguration in validationParameters.ConfigurationManager.GetValidLkgConfigurations())
+ {
+ if (!lkgConfiguration.Equals(currentConfiguration) && TokenUtilities.IsRecoverableConfiguration(jsonWebToken.Kid, currentConfiguration, lkgConfiguration, recoverableException))
+ {
+ tokenValidationResult = jsonWebToken.IsEncrypted ?
+ await ValidateJWEAsync(jsonWebToken, validationParameters, lkgConfiguration).ConfigureAwait(false) :
+ await ValidateJWSAsync(jsonWebToken, validationParameters, lkgConfiguration).ConfigureAwait(false);
+
+ if (tokenValidationResult.IsValid)
+ return tokenValidationResult;
+ }
+ }
+ }
+ }
+ }
+
+ return tokenValidationResult;
+ }
+
+ internal async ValueTask ValidateTokenPayloadAsync(
+ JsonWebToken jsonWebToken,
+ TokenValidationParameters validationParameters,
+ BaseConfiguration configuration)
+ {
+ var expires = jsonWebToken.HasPayloadClaim(JwtRegisteredClaimNames.Exp) ? (DateTime?)jsonWebToken.ValidTo : null;
+ var notBefore = jsonWebToken.HasPayloadClaim(JwtRegisteredClaimNames.Nbf) ? (DateTime?)jsonWebToken.ValidFrom : null;
+
+ Validators.ValidateLifetime(notBefore, expires, jsonWebToken, validationParameters);
+ Validators.ValidateAudience(jsonWebToken.Audiences, jsonWebToken, validationParameters);
+ string issuer = await Validators.ValidateIssuerAsync(jsonWebToken.Issuer, jsonWebToken, validationParameters, configuration).ConfigureAwait(false);
+
+ Validators.ValidateTokenReplay(expires, jsonWebToken.EncodedToken, validationParameters);
+ if (validationParameters.ValidateActor && !string.IsNullOrWhiteSpace(jsonWebToken.Actor))
+ {
+ // Infinite recursion should not occur here, as the JsonWebToken passed into this method is (1) constructed from a string
+ // AND (2) the signature is successfully validated on it. (1) implies that even if there are nested actor tokens,
+ // they must end at some point since they cannot reference one another. (2) means that the token has a valid signature
+ // and (since issuer validation occurs first) came from a trusted authority.
+ // NOTE: More than one nested actor token should not be considered a valid token, but if we somehow encounter one,
+ // this code will still work properly.
+ TokenValidationResult tokenValidationResult =
+ await ValidateTokenAsync(jsonWebToken.Actor, validationParameters.ActorValidationParameters ?? validationParameters).ConfigureAwait(false);
+
+ if (!tokenValidationResult.IsValid)
+ return tokenValidationResult;
+ }
+
+ string tokenType = Validators.ValidateTokenType(jsonWebToken.Typ, jsonWebToken, validationParameters);
+ return new TokenValidationResult(jsonWebToken, this, validationParameters.Clone(), issuer)
+ {
+ IsValid = true,
+ TokenType = tokenType
+ };
+ }
+
+ internal async ValueTask ValidateTokenPayloadAsync(
+ JsonWebToken jsonWebToken,
+ TokenValidationParameters validationParameters,
+ CallContext callContext,
+ CancellationToken cancellationToken)
+ {
+ var expires = jsonWebToken.HasPayloadClaim(JwtRegisteredClaimNames.Exp) ? (DateTime?)jsonWebToken.ValidTo : null;
+ var notBefore = jsonWebToken.HasPayloadClaim(JwtRegisteredClaimNames.Nbf) ? (DateTime?)jsonWebToken.ValidFrom : null;
+
+ Validators.ValidateLifetime(notBefore, expires, jsonWebToken, validationParameters);
+ Validators.ValidateAudience(jsonWebToken.Audiences, jsonWebToken, validationParameters);
+
+ IssuerValidationResult issuerValidationResult = await Validators.ValidateIssuerAsync(
+ jsonWebToken.Issuer,
+ jsonWebToken,
+ validationParameters,
+ callContext,
+ cancellationToken).ConfigureAwait(false);
+
+ if (!issuerValidationResult.IsValid)
+ {
+ return new TokenValidationResult(jsonWebToken, this, validationParameters, issuerValidationResult.Issuer)
+ {
+ IsValid = false,
+ Exception = issuerValidationResult.Exception
+ };
+ }
+
+ Validators.ValidateTokenReplay(expires, jsonWebToken.EncodedToken, validationParameters);
+ if (validationParameters.ValidateActor && !string.IsNullOrWhiteSpace(jsonWebToken.Actor))
+ {
+ // Infinite recursion should not occur here, as the JsonWebToken passed into this method is (1) constructed from a string
+ // AND (2) the signature is successfully validated on it. (1) implies that even if there are nested actor tokens,
+ // they must end at some point since they cannot reference one another. (2) means that the token has a valid signature
+ // and (since issuer validation occurs first) came from a trusted authority.
+ // NOTE: More than one nested actor token should not be considered a valid token, but if we somehow encounter one,
+ // this code will still work properly.
+ TokenValidationResult tokenValidationResult =
+ await ValidateTokenAsync(jsonWebToken.Actor, validationParameters.ActorValidationParameters ?? validationParameters).ConfigureAwait(false);
+
+ if (!tokenValidationResult.IsValid)
+ return tokenValidationResult;
+ }
+
+ string tokenType = Validators.ValidateTokenType(jsonWebToken.Typ, jsonWebToken, validationParameters);
+ return new TokenValidationResult(jsonWebToken, this, validationParameters.Clone(), issuerValidationResult.Issuer)
+ {
+ IsValid = true,
+ TokenType = tokenType
+ };
+ }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
index cf4ad2e264..43d1999a3c 100644
--- a/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
+++ b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
@@ -3,12 +3,8 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Security.Claims;
-using System.Text;
using System.Text.RegularExpressions;
-using System.Threading;
-using System.Threading.Tasks;
using Microsoft.IdentityModel.Abstractions;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;
@@ -174,15 +170,6 @@ public virtual bool CanReadToken(string token)
}
}
- ///
- /// Returns a value that indicates if this handler can validate a .
- ///
- /// 'true', indicating this instance can validate a .
- public virtual bool CanValidateToken
- {
- get { return true; }
- }
-
private static StringComparison GetStringComparisonRuleIf509(SecurityKey securityKey) => (securityKey is X509SecurityKey)
? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
@@ -498,90 +485,6 @@ public override SecurityToken ReadToken(string token)
return ReadJsonWebToken(token);
}
- ///
- /// Validates a JWS or a JWE.
- ///
- /// A 'JSON Web Token' (JWT) in JWS or JWE Compact Serialization Format.
- /// A required for validation.
- /// A
- [Obsolete("`JsonWebTokens.ValidateToken(string, TokenValidationParameters)` has been deprecated and will be removed in a future release. Use `JsonWebTokens.ValidateTokenAsync(string, TokenValidationParameters)` instead. For more information, see https://aka.ms/IdentityModel/7-breaking-changes", false)]
- public virtual TokenValidationResult ValidateToken(string token, TokenValidationParameters validationParameters)
- {
- return ValidateTokenAsync(token, validationParameters).ConfigureAwait(false).GetAwaiter().GetResult();
- }
-
- ///
- /// Validates a token.
- /// On a validation failure, no exception will be thrown; instead, the exception will be set in the returned TokenValidationResult.Exception property.
- /// Callers should always check the TokenValidationResult.IsValid property to verify the validity of the result.
- ///
- /// The token to be validated.
- /// A required for validation.
- /// A
- ///
- /// TokenValidationResult.Exception will be set to one of the following exceptions if the is invalid.
- /// if is null or empty.
- /// if is null.
- /// 'token.Length' is greater than .
- /// if is not a valid ,
- /// if the validationParameters.TokenReader delegate is not able to parse/read the token as a valid ,
- ///
- public override async Task ValidateTokenAsync(string token, TokenValidationParameters validationParameters)
- {
- if (string.IsNullOrEmpty(token))
- return new TokenValidationResult { Exception = LogHelper.LogArgumentNullException(nameof(token)), IsValid = false };
-
- if (validationParameters == null)
- return new TokenValidationResult { Exception = LogHelper.LogArgumentNullException(nameof(validationParameters)), IsValid = false };
-
- if (token.Length > MaximumTokenSizeInBytes)
- return new TokenValidationResult { Exception = LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(TokenLogMessages.IDX10209, LogHelper.MarkAsNonPII(token.Length), LogHelper.MarkAsNonPII(MaximumTokenSizeInBytes)))), IsValid = false };
-
- try
- {
- TokenValidationResult result = ReadToken(token, validationParameters);
- if (result.IsValid)
- return await ValidateTokenAsync(result.SecurityToken, validationParameters).ConfigureAwait(false);
-
- return result;
- }
- catch (Exception ex)
- {
- return new TokenValidationResult
- {
- Exception = ex,
- IsValid = false
- };
- }
- }
-
- ///
- public override async Task ValidateTokenAsync(SecurityToken token, TokenValidationParameters validationParameters)
- {
- if (token == null)
- throw LogHelper.LogArgumentNullException(nameof(token));
-
- if (validationParameters == null)
- return new TokenValidationResult { Exception = LogHelper.LogArgumentNullException(nameof(validationParameters)), IsValid = false };
-
- var jwt = token as JsonWebToken;
- if (jwt == null)
- return new TokenValidationResult { Exception = LogHelper.LogArgumentException(nameof(token), $"{nameof(token)} must be a {nameof(JsonWebToken)}."), IsValid = false };
-
- try
- {
- return await ValidateTokenAsync(jwt, validationParameters).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- return new TokenValidationResult
- {
- Exception = ex,
- IsValid = false
- };
- }
- }
-
///
/// Converts a string into an instance of .
///
@@ -627,453 +530,5 @@ private static TokenValidationResult ReadToken(string token, TokenValidationPara
IsValid = true
};
}
-
- ///
- /// Private method for token validation, responsible for:
- /// (1) Obtaining a configuration from the .
- /// (2) Revalidating using the Last Known Good Configuration (if present), and obtaining a refreshed configuration (if necessary) and revalidating using it.
- ///
- /// The JWT token
- /// The to be used for validation.
- ///
- private async ValueTask ValidateTokenAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters)
- {
- BaseConfiguration currentConfiguration = null;
- if (validationParameters.ConfigurationManager != null)
- {
- try
- {
- currentConfiguration = await validationParameters.ConfigurationManager.GetBaseConfigurationAsync(CancellationToken.None).ConfigureAwait(false);
- }
-#pragma warning disable CA1031 // Do not catch general exception types
- catch (Exception ex)
-#pragma warning restore CA1031 // Do not catch general exception types
- {
- // The exception is not re-thrown as the TokenValidationParameters may have the issuer and signing key set
- // directly on them, allowing the library to continue with token validation.
- if (LogHelper.IsEnabled(EventLogLevel.Warning))
- LogHelper.LogWarning(LogHelper.FormatInvariant(TokenLogMessages.IDX10261, validationParameters.ConfigurationManager.MetadataAddress, ex.ToString()));
- }
- }
-
- TokenValidationResult tokenValidationResult = await ValidateTokenAsync(jsonWebToken, validationParameters, currentConfiguration).ConfigureAwait(false);
- if (validationParameters.ConfigurationManager != null)
- {
- if (tokenValidationResult.IsValid)
- {
- // Set current configuration as LKG if it exists.
- if (currentConfiguration != null)
- validationParameters.ConfigurationManager.LastKnownGoodConfiguration = currentConfiguration;
-
- return tokenValidationResult;
- }
- else if (TokenUtilities.IsRecoverableException(tokenValidationResult.Exception))
- {
- // If we were still unable to validate, attempt to refresh the configuration and validate using it
- // but ONLY if the currentConfiguration is not null. We want to avoid refreshing the configuration on
- // retrieval error as this case should have already been hit before. This refresh handles the case
- // where a new valid configuration was somehow published during validation time.
- if (currentConfiguration != null)
- {
- validationParameters.ConfigurationManager.RequestRefresh();
- validationParameters.RefreshBeforeValidation = true;
- var lastConfig = currentConfiguration;
- currentConfiguration = await validationParameters.ConfigurationManager.GetBaseConfigurationAsync(CancellationToken.None).ConfigureAwait(false);
-
- // Only try to re-validate using the newly obtained config if it doesn't reference equal the previously used configuration.
- if (lastConfig != currentConfiguration)
- {
- tokenValidationResult = await ValidateTokenAsync(jsonWebToken, validationParameters, currentConfiguration).ConfigureAwait(false);
-
- if (tokenValidationResult.IsValid)
- {
- validationParameters.ConfigurationManager.LastKnownGoodConfiguration = currentConfiguration;
- return tokenValidationResult;
- }
- }
- }
-
- if (validationParameters.ConfigurationManager.UseLastKnownGoodConfiguration)
- {
- validationParameters.RefreshBeforeValidation = false;
- validationParameters.ValidateWithLKG = true;
- var recoverableException = tokenValidationResult.Exception;
-
- foreach (BaseConfiguration lkgConfiguration in validationParameters.ConfigurationManager.GetValidLkgConfigurations())
- {
- if (!lkgConfiguration.Equals(currentConfiguration) && TokenUtilities.IsRecoverableConfiguration(jsonWebToken.Kid, currentConfiguration, lkgConfiguration, recoverableException))
- {
- tokenValidationResult = await ValidateTokenAsync(jsonWebToken, validationParameters, lkgConfiguration).ConfigureAwait(false);
-
- if (tokenValidationResult.IsValid)
- return tokenValidationResult;
- }
- }
- }
- }
- }
-
- return tokenValidationResult;
- }
-
- private ValueTask ValidateTokenAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
- {
- return jsonWebToken.IsEncrypted ?
- ValidateJWEAsync(jsonWebToken, validationParameters, configuration) :
- ValidateJWSAsync(jsonWebToken, validationParameters, configuration);
- }
-
- private async ValueTask ValidateJWSAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
- {
- try
- {
- TokenValidationResult tokenValidationResult;
- if (validationParameters.TransformBeforeSignatureValidation != null)
- jsonWebToken = validationParameters.TransformBeforeSignatureValidation(jsonWebToken, validationParameters) as JsonWebToken;
-
- if (validationParameters.SignatureValidator != null || validationParameters.SignatureValidatorUsingConfiguration != null)
- {
- var validatedToken = ValidateSignatureUsingDelegates(jsonWebToken, validationParameters, configuration);
- tokenValidationResult = await ValidateTokenPayloadAsync(validatedToken, validationParameters, configuration).ConfigureAwait(false);
- Validators.ValidateIssuerSecurityKey(validatedToken.SigningKey, validatedToken, validationParameters, configuration);
- }
- else
- {
- if (validationParameters.ValidateSignatureLast)
- {
- tokenValidationResult = await ValidateTokenPayloadAsync(jsonWebToken, validationParameters, configuration).ConfigureAwait(false);
- if (tokenValidationResult.IsValid)
- tokenValidationResult.SecurityToken = ValidateSignatureAndIssuerSecurityKey(jsonWebToken, validationParameters, configuration);
- }
- else
- {
- var validatedToken = ValidateSignatureAndIssuerSecurityKey(jsonWebToken, validationParameters, configuration);
- tokenValidationResult = await ValidateTokenPayloadAsync(validatedToken, validationParameters, configuration).ConfigureAwait(false);
- }
- }
-
- return tokenValidationResult;
- }
-#pragma warning disable CA1031 // Do not catch general exception types
- catch (Exception ex)
-#pragma warning restore CA1031 // Do not catch general exception types
- {
- return new TokenValidationResult
- {
- Exception = ex,
- IsValid = false,
- TokenOnFailedValidation = validationParameters.IncludeTokenOnFailedValidation ? jsonWebToken : null
- };
- }
- }
-
- private async ValueTask ValidateJWEAsync(JsonWebToken jwtToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
- {
- try
- {
- TokenValidationResult tokenValidationResult = ReadToken(DecryptToken(jwtToken, validationParameters, configuration), validationParameters);
- if (!tokenValidationResult.IsValid)
- return tokenValidationResult;
-
- tokenValidationResult = await ValidateJWSAsync(tokenValidationResult.SecurityToken as JsonWebToken, validationParameters, configuration).ConfigureAwait(false);
- if (!tokenValidationResult.IsValid)
- return tokenValidationResult;
-
- jwtToken.InnerToken = tokenValidationResult.SecurityToken as JsonWebToken;
- jwtToken.Payload = (tokenValidationResult.SecurityToken as JsonWebToken).Payload;
- return new TokenValidationResult
- {
- SecurityToken = jwtToken,
- ClaimsIdentityNoLocking = tokenValidationResult.ClaimsIdentityNoLocking,
- IsValid = true,
- TokenType = tokenValidationResult.TokenType
- };
- }
-#pragma warning disable CA1031 // Do not catch general exception types
- catch (Exception ex)
-#pragma warning restore CA1031 // Do not catch general exception types
- {
- return new TokenValidationResult
- {
- Exception = ex,
- IsValid = false,
- TokenOnFailedValidation = validationParameters.IncludeTokenOnFailedValidation ? jwtToken : null
- };
- }
- }
-
- private static JsonWebToken ValidateSignatureUsingDelegates(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
- {
- if (validationParameters.SignatureValidatorUsingConfiguration != null)
- {
- var validatedToken = validationParameters.SignatureValidatorUsingConfiguration(jsonWebToken.EncodedToken, validationParameters, configuration);
- if (validatedToken == null)
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10505, jsonWebToken)));
-
- if (!(validatedToken is JsonWebToken validatedJsonWebToken))
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10506, LogHelper.MarkAsNonPII(typeof(JsonWebToken)), LogHelper.MarkAsNonPII(validatedToken.GetType()), jsonWebToken)));
-
- return validatedJsonWebToken;
- }
- else if (validationParameters.SignatureValidator != null)
- {
- var validatedToken = validationParameters.SignatureValidator(jsonWebToken.EncodedToken, validationParameters);
- if (validatedToken == null)
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10505, jsonWebToken)));
-
- if (!(validatedToken is JsonWebToken validatedJsonWebToken))
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10506, LogHelper.MarkAsNonPII(typeof(JsonWebToken)), LogHelper.MarkAsNonPII(validatedToken.GetType()), jsonWebToken)));
-
- return validatedJsonWebToken;
- }
-
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10505, jsonWebToken)));
- }
-
- private static JsonWebToken ValidateSignatureAndIssuerSecurityKey(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
- {
- JsonWebToken validatedToken = ValidateSignature(jsonWebToken, validationParameters, configuration);
- Validators.ValidateIssuerSecurityKey(validatedToken.SigningKey, jsonWebToken, validationParameters, configuration);
-
- return validatedToken;
- }
-
- private async ValueTask ValidateTokenPayloadAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
- {
- var expires = jsonWebToken.HasPayloadClaim(JwtRegisteredClaimNames.Exp) ? (DateTime?)jsonWebToken.ValidTo : null;
- var notBefore = jsonWebToken.HasPayloadClaim(JwtRegisteredClaimNames.Nbf) ? (DateTime?)jsonWebToken.ValidFrom : null;
-
- Validators.ValidateLifetime(notBefore, expires, jsonWebToken, validationParameters);
- Validators.ValidateAudience(jsonWebToken.Audiences, jsonWebToken, validationParameters);
- string issuer = await Validators.ValidateIssuerAsync(jsonWebToken.Issuer, jsonWebToken, validationParameters, configuration).ConfigureAwait(false);
-
- Validators.ValidateTokenReplay(expires, jsonWebToken.EncodedToken, validationParameters);
- if (validationParameters.ValidateActor && !string.IsNullOrWhiteSpace(jsonWebToken.Actor))
- {
- // Infinite recursion should not occur here, as the JsonWebToken passed into this method is (1) constructed from a string
- // AND (2) the signature is successfully validated on it. (1) implies that even if there are nested actor tokens,
- // they must end at some point since they cannot reference one another. (2) means that the token has a valid signature
- // and (since issuer validation occurs first) came from a trusted authority.
- // NOTE: More than one nested actor token should not be considered a valid token, but if we somehow encounter one,
- // this code will still work properly.
- TokenValidationResult tokenValidationResult =
- await ValidateTokenAsync(jsonWebToken.Actor, validationParameters.ActorValidationParameters ?? validationParameters).ConfigureAwait(false);
-
- if (!tokenValidationResult.IsValid)
- return tokenValidationResult;
- }
-
- string tokenType = Validators.ValidateTokenType(jsonWebToken.Typ, jsonWebToken, validationParameters);
- return new TokenValidationResult(jsonWebToken, this, validationParameters.Clone(), issuer)
- {
- IsValid = true,
- TokenType = tokenType
- };
- }
-
- ///
- /// Validates the JWT signature.
- ///
- private static JsonWebToken ValidateSignature(JsonWebToken jwtToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
- {
- bool kidMatched = false;
- IEnumerable keys = null;
-
- if (!jwtToken.IsSigned)
- {
- if (validationParameters.RequireSignedTokens)
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10504, jwtToken)));
- else
- return jwtToken;
- }
-
- if (validationParameters.IssuerSigningKeyResolverUsingConfiguration != null)
- {
- keys = validationParameters.IssuerSigningKeyResolverUsingConfiguration(jwtToken.EncodedToken, jwtToken, jwtToken.Kid, validationParameters, configuration);
- }
- else if (validationParameters.IssuerSigningKeyResolver != null)
- {
- keys = validationParameters.IssuerSigningKeyResolver(jwtToken.EncodedToken, jwtToken, jwtToken.Kid, validationParameters);
- }
- else
- {
- var key = JwtTokenUtilities.ResolveTokenSigningKey(jwtToken.Kid, jwtToken.X5t, validationParameters, configuration);
- if (key != null)
- {
- kidMatched = true;
- keys = [key];
- }
- }
-
- if (validationParameters.TryAllIssuerSigningKeys && keys.IsNullOrEmpty())
- {
- // control gets here if:
- // 1. User specified delegate: IssuerSigningKeyResolver returned null
- // 2. ResolveIssuerSigningKey returned null
- // Try all the keys. This is the degenerate case, not concerned about perf.
- keys = TokenUtilities.GetAllSigningKeys(configuration, validationParameters);
- }
-
- // keep track of exceptions thrown, keys that were tried
- StringBuilder exceptionStrings = null;
- StringBuilder keysAttempted = null;
- var kidExists = !string.IsNullOrEmpty(jwtToken.Kid);
-
- if (keys != null)
- {
- foreach (var key in keys)
- {
- try
- {
- if (ValidateSignature(jwtToken, key, validationParameters))
- {
- if (LogHelper.IsEnabled(EventLogLevel.Informational))
- LogHelper.LogInformation(TokenLogMessages.IDX10242, jwtToken);
-
- jwtToken.SigningKey = key;
- return jwtToken;
- }
- }
- catch (Exception ex)
- {
- (exceptionStrings ??= new StringBuilder()).AppendLine(ex.ToString());
- }
-
- if (key != null)
- {
- (keysAttempted ??= new StringBuilder()).Append(key.ToString()).Append(" , KeyId: ").AppendLine(key.KeyId);
- if (kidExists && !kidMatched && key.KeyId != null)
- kidMatched = jwtToken.Kid.Equals(key.KeyId, key is X509SecurityKey ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
- }
- }
- }
-
- // Get information on where keys used during token validation came from for debugging purposes.
- var keysInTokenValidationParameters = TokenUtilities.GetAllSigningKeys(validationParameters: validationParameters);
- var keysInConfiguration = TokenUtilities.GetAllSigningKeys(configuration);
- var numKeysInTokenValidationParameters = keysInTokenValidationParameters.Count();
- var numKeysInConfiguration = keysInConfiguration.Count();
-
- if (kidExists)
- {
- if (kidMatched)
- {
- JsonWebToken localJwtToken = jwtToken; // avoid closure on non-exceptional path
- var isKidInTVP = keysInTokenValidationParameters.Any(x => x.KeyId.Equals(localJwtToken.Kid));
- var keyLocation = isKidInTVP ? "TokenValidationParameters" : "Configuration";
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10511,
- LogHelper.MarkAsNonPII((object)keysAttempted ?? ""),
- LogHelper.MarkAsNonPII(numKeysInTokenValidationParameters),
- LogHelper.MarkAsNonPII(numKeysInConfiguration),
- LogHelper.MarkAsNonPII(keyLocation),
- LogHelper.MarkAsNonPII(jwtToken.Kid),
- (object)exceptionStrings ?? "",
- jwtToken)));
- }
-
- if (!validationParameters.ValidateSignatureLast)
- {
- InternalValidators.ValidateAfterSignatureFailed(
- jwtToken,
- jwtToken.ValidFromNullable,
- jwtToken.ValidToNullable,
- jwtToken.Audiences,
- validationParameters,
- configuration);
- }
- }
-
- if (keysAttempted is not null)
- {
- if (kidExists)
- {
- throw LogHelper.LogExceptionMessage(new SecurityTokenSignatureKeyNotFoundException(LogHelper.FormatInvariant(TokenLogMessages.IDX10503,
- LogHelper.MarkAsNonPII(jwtToken.Kid),
- LogHelper.MarkAsNonPII((object)keysAttempted ?? ""),
- LogHelper.MarkAsNonPII(numKeysInTokenValidationParameters),
- LogHelper.MarkAsNonPII(numKeysInConfiguration),
- (object)exceptionStrings ?? "",
- jwtToken)));
- }
- else
- {
- throw LogHelper.LogExceptionMessage(new SecurityTokenSignatureKeyNotFoundException(LogHelper.FormatInvariant(TokenLogMessages.IDX10517,
- LogHelper.MarkAsNonPII((object)keysAttempted ?? ""),
- LogHelper.MarkAsNonPII(numKeysInTokenValidationParameters),
- LogHelper.MarkAsNonPII(numKeysInConfiguration),
- (object)exceptionStrings ?? "",
- jwtToken)));
- }
- }
-
- throw LogHelper.LogExceptionMessage(new SecurityTokenSignatureKeyNotFoundException(TokenLogMessages.IDX10500));
- }
-
- internal static bool IsSignatureValid(byte[] signatureBytes, int signatureBytesLength, SignatureProvider signatureProvider, byte[] dataToVerify, int dataToVerifyLength)
- {
- if (signatureProvider is SymmetricSignatureProvider)
- {
- return signatureProvider.Verify(dataToVerify, 0, dataToVerifyLength, signatureBytes, 0, signatureBytesLength);
- }
- else
- {
- if (signatureBytes.Length == signatureBytesLength)
- {
- return signatureProvider.Verify(dataToVerify, 0, dataToVerifyLength, signatureBytes, 0, signatureBytesLength);
- }
- else
- {
- byte[] sigBytes = new byte[signatureBytesLength];
- Array.Copy(signatureBytes, 0, sigBytes, 0, signatureBytesLength);
- return signatureProvider.Verify(dataToVerify, 0, dataToVerifyLength, sigBytes, 0, signatureBytesLength);
- }
- }
- }
-
- internal static bool ValidateSignature(byte[] bytes, int len, string stringWithSignature, int signatureStartIndex, SignatureProvider signatureProvider)
- {
- return Base64UrlEncoding.Decode(
- stringWithSignature,
- signatureStartIndex + 1,
- stringWithSignature.Length - signatureStartIndex - 1,
- signatureProvider,
- bytes,
- len,
- IsSignatureValid);
- }
-
- internal static bool ValidateSignature(JsonWebToken jsonWebToken, SecurityKey key, TokenValidationParameters validationParameters)
- {
- var cryptoProviderFactory = validationParameters.CryptoProviderFactory ?? key.CryptoProviderFactory;
- if (!cryptoProviderFactory.IsSupportedAlgorithm(jsonWebToken.Alg, key))
- {
- if (LogHelper.IsEnabled(EventLogLevel.Informational))
- LogHelper.LogInformation(LogMessages.IDX14000, LogHelper.MarkAsNonPII(jsonWebToken.Alg), key);
-
- return false;
- }
-
- Validators.ValidateAlgorithm(jsonWebToken.Alg, key, jsonWebToken, validationParameters);
- var signatureProvider = cryptoProviderFactory.CreateForVerifying(key, jsonWebToken.Alg);
- try
- {
- if (signatureProvider == null)
- throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(TokenLogMessages.IDX10636, key == null ? "Null" : key.ToString(), LogHelper.MarkAsNonPII(jsonWebToken.Alg))));
-
- return EncodingUtils.PerformEncodingDependentOperation(
- jsonWebToken.EncodedToken,
- 0,
- jsonWebToken.Dot2,
- Encoding.UTF8,
- jsonWebToken.EncodedToken,
- jsonWebToken.Dot2,
- signatureProvider,
- ValidateSignature);
- }
- finally
- {
- cryptoProviderFactory.ReleaseSignatureProvider(signatureProvider);
- }
- }
}
}
diff --git a/src/Microsoft.IdentityModel.KeyVaultExtensions/InternalsVisibleTo.cs b/src/Microsoft.IdentityModel.KeyVaultExtensions/InternalsVisibleTo.cs
deleted file mode 100644
index 5e625e7a84..0000000000
--- a/src/Microsoft.IdentityModel.KeyVaultExtensions/InternalsVisibleTo.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.KeyVaultExtensions.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
diff --git a/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultCryptoProvider.cs b/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultCryptoProvider.cs
deleted file mode 100644
index 7eecfe8d82..0000000000
--- a/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultCryptoProvider.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using System.Linq;
-using Microsoft.Azure.KeyVault.WebKey;
-using Microsoft.IdentityModel.Logging;
-using Microsoft.IdentityModel.Tokens;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions
-{
- ///
- /// Provides cryptographic operators based on Azure Key Vault.
- ///
- public class KeyVaultCryptoProvider : ICryptoProvider
- {
- private readonly CryptoProviderCache _cache;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public KeyVaultCryptoProvider()
- {
- _cache = new InMemoryCryptoProviderCache();
- }
-
- ///
- /// Gets the
- ///
- internal CryptoProviderCache CryptoProviderCache => _cache;
-
- ///
- /// Returns a cryptographic operator that supports the algorithm.
- ///
- /// the algorithm that defines the cryptographic operator.
- /// the arguments required by the cryptographic operator. May be null.
- /// if is null or empty.
- /// if is null.
- /// if does not contain a .
- /// call when finished with the object.
- public object Create(string algorithm, params object[] args)
- {
- if (string.IsNullOrEmpty(algorithm))
- throw LogHelper.LogArgumentNullException(nameof(algorithm));
-
- if (args == null)
- throw LogHelper.LogArgumentNullException(nameof(args));
-
- if (args.FirstOrDefault() is KeyVaultSecurityKey key)
- {
- if (JsonWebKeyEncryptionAlgorithm.AllAlgorithms.Contains(algorithm, StringComparer.Ordinal))
- return new KeyVaultKeyWrapProvider(key, algorithm);
- else if (JsonWebKeySignatureAlgorithm.AllAlgorithms.Contains(algorithm, StringComparer.Ordinal))
- {
- var willCreateSignatures = (bool)(args.Skip(1).FirstOrDefault() ?? false);
-
- if (_cache.TryGetSignatureProvider(key, algorithm, typeofProvider: key.GetType().ToString(), willCreateSignatures, out var cachedProvider))
- return cachedProvider;
-
- var signatureProvider = new KeyVaultSignatureProvider(key, algorithm, willCreateSignatures);
- if (CryptoProviderFactory.ShouldCacheSignatureProvider(signatureProvider))
- _cache.TryAdd(signatureProvider);
-
- return signatureProvider;
- }
- }
-
- throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10652, LogHelper.MarkAsNonPII(algorithm))));
- }
-
- ///
- /// Called to determine if a cryptographic operation is supported.
- ///
- /// the algorithm that defines the cryptographic operator.
- /// the arguments required by the cryptographic operator. May be null.
- /// true if supported
- public bool IsSupportedAlgorithm(string algorithm, params object[] args)
- {
- if (string.IsNullOrEmpty(algorithm))
- throw LogHelper.LogArgumentNullException(nameof(algorithm));
-
- if (args == null)
- throw LogHelper.LogArgumentNullException(nameof(args));
-
- return args.FirstOrDefault() is KeyVaultSecurityKey
- && (JsonWebKeyEncryptionAlgorithm.AllAlgorithms.Contains(algorithm, StringComparer.Ordinal) || JsonWebKeySignatureAlgorithm.AllAlgorithms.Contains(algorithm, StringComparer.Ordinal));
- }
-
- ///
- /// Called to release the object returned from
- ///
- /// the object returned from .
- public void Release(object cryptoInstance)
- {
- if (cryptoInstance is SignatureProvider signatureProvider)
- _cache.TryRemove(signatureProvider);
-
- if (cryptoInstance is IDisposable obj)
- obj.Dispose();
- }
- }
-}
diff --git a/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultKeyWrapProvider.cs b/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultKeyWrapProvider.cs
deleted file mode 100644
index 63c625fe03..0000000000
--- a/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultKeyWrapProvider.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Azure.KeyVault;
-using Microsoft.IdentityModel.Logging;
-using Microsoft.IdentityModel.Tokens;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions
-{
- ///
- /// Provides wrap and unwrap operations using Azure Key Vault.
- ///
- public class KeyVaultKeyWrapProvider : KeyWrapProvider
- {
- private readonly IKeyVaultClient _client;
- private readonly KeyVaultSecurityKey _key;
- private readonly string _algorithm;
- private bool _disposed = false;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The that will be used for key wrap operations.
- /// The key wrap algorithm to apply.
- /// if is null.
- /// if is not a .
- /// if is null or empty.
- public KeyVaultKeyWrapProvider(SecurityKey key, string algorithm)
- : this(key, algorithm, null)
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The that will be used for key wrap operations.
- /// The key wrap algorithm to apply.
- /// A mock used for testing purposes.
- internal KeyVaultKeyWrapProvider(SecurityKey key, string algorithm, IKeyVaultClient? client)
- {
- _algorithm = string.IsNullOrEmpty(algorithm) ? throw LogHelper.LogArgumentNullException(nameof(algorithm)) : algorithm;
- if (key == null)
- throw LogHelper.LogArgumentNullException(nameof(key));
-
- _key = key as KeyVaultSecurityKey ?? throw LogHelper.LogExceptionMessage(new NotSupportedException(key.GetType().ToString()));
- _client = client ?? new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(_key.Callback!));
- }
-
- ///
- /// Gets the KeyWrap algorithm that is being used.
- ///
- public override string Algorithm => _algorithm;
-
- ///
- /// Gets or sets a user context for a .
- ///
- /// This is null by default. This can be used by runtimes or for extensibility scenarios.
- public override string? Context { get; set; }
-
- ///
- /// Gets the that is being used.
- ///
- public override SecurityKey Key => _key;
-
- ///
- /// Unwrap a key.
- ///
- /// key to unwrap.
- /// if is null.
- /// if .Length == 0.
- /// Unwrapped key.
- public override byte[] UnwrapKey(byte[] keyBytes)
- {
- return UnwrapKeyAsync(keyBytes, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult();
- }
-
- ///
- /// Wrap a key.
- ///
- /// the key to be wrapped
- /// if is null.
- /// if .Length == 0.
- /// wrapped key.
- public override byte[] WrapKey(byte[] keyBytes)
- {
- return WrapKeyAsync(keyBytes, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult();
- }
-
- ///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///
- /// true, if called from Dispose(), false, if invoked inside a finalizer
- protected override void Dispose(bool disposing)
- {
- if (!_disposed)
- {
- if (disposing)
- {
- _disposed = true;
- _client.Dispose();
- }
- }
- }
-
- ///
- /// Unwraps a symmetric key using Azure Key Vault.
- ///
- /// key to unwrap.
- /// Propagates notification that operations should be canceled.
- /// if is null.
- /// if .Length == 0.
- /// Unwrapped key.
- private async Task UnwrapKeyAsync(byte[] keyBytes, CancellationToken cancellation)
- {
- if (keyBytes == null || keyBytes.Length == 0)
- throw LogHelper.LogArgumentNullException(nameof(keyBytes));
-
- return (await _client.UnwrapKeyAsync(_key.KeyId, Algorithm, keyBytes, cancellation).ConfigureAwait(false)).Result;
- }
-
- ///
- /// Wraps a symmetric key using Azure Key Vault.
- ///
- /// the key to be wrapped
- /// Propagates notification that operations should be canceled.
- /// if is null.
- /// if .Length == 0.
- /// wrapped key.
- private async Task WrapKeyAsync(byte[] keyBytes, CancellationToken cancellation)
- {
- if (keyBytes == null || keyBytes.Length == 0)
- throw LogHelper.LogArgumentNullException(nameof(keyBytes));
-
- return (await _client.WrapKeyAsync(_key.KeyId, Algorithm, keyBytes, cancellation).ConfigureAwait(false)).Result;
- }
- }
-}
diff --git a/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultSecurityKey.cs b/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultSecurityKey.cs
deleted file mode 100644
index 9a56ce27e8..0000000000
--- a/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultSecurityKey.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using System.Collections;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Azure.KeyVault;
-using Microsoft.IdentityModel.Logging;
-using Microsoft.IdentityModel.Tokens;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions
-{
- ///
- /// Provides signing and verifying operations using Azure Key Vault.
- ///
- public class KeyVaultSecurityKey : SecurityKey
- {
- private int? _keySize;
- private string? _keyId;
-
- ///
- /// The authentication callback delegate which is to be implemented by the client code.
- ///
- /// Identifier of the authority, a URL.
- /// Identifier of the target resource that is the recipient of the requested token, a URL.
- /// The scope of the authentication request.
- /// An access token for Azure Key Vault.
- public delegate Task AuthenticationCallback(string authority, string resource, string scope);
-
- ///
- /// Initializes a new instance of the class.
- ///
- protected KeyVaultSecurityKey()
- {
-
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The key identifier that is recognized by KeyVault.
- /// The authentication callback that will obtain the access_token for KeyVault.
- /// if is null or empty.
- /// if is null.
- public KeyVaultSecurityKey(string keyIdentifier, AuthenticationCallback callback)
- {
- Callback = callback ?? throw LogHelper.LogArgumentNullException(nameof(callback));
- KeyId = keyIdentifier;
- }
-
- internal KeyVaultSecurityKey(string keyIdentifier, int keySize)
- {
- _keyId = keyIdentifier;
- _keySize = keySize;
- }
-
- ///
- /// The authentication callback delegate that retrieves an access token for the KeyVault.
- ///
- public AuthenticationCallback? Callback { get; protected set; }
-
- ///
- /// The uniform resource identifier of the security key.
- ///
- public override string KeyId
- {
- get => _keyId!;
- set
- {
- if (string.IsNullOrEmpty(value))
- throw LogHelper.LogArgumentNullException(nameof(value));
- else if (StringComparer.Ordinal.Equals(_keyId, value))
- return;
-
- _keyId = value;
-
- // Reset the properties so they can be retrieved from Azure KeyVault the next time they are accessed.
- _keySize = null;
- }
- }
-
- ///
- /// The size of the security key.
- ///
- public override int KeySize
- {
- get
- {
- if (!_keySize.HasValue)
- Initialize();
-
- return _keySize!.Value;
- }
- }
-
- ///
- /// Retrieve the properties from Azure Key Vault.
- ///
- private void Initialize()
- {
- using (var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(Callback!)))
- {
- var bundle = client.GetKeyAsync(_keyId, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult();
- _keySize = new BitArray(bundle.Key.N).Length;
- }
- }
- }
-}
diff --git a/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultSignatureProvider.cs b/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultSignatureProvider.cs
deleted file mode 100644
index 38478482fd..0000000000
--- a/src/Microsoft.IdentityModel.KeyVaultExtensions/KeyVaultSignatureProvider.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using System.Security.Cryptography;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Azure.KeyVault;
-using Microsoft.IdentityModel.Logging;
-using Microsoft.IdentityModel.Tokens;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions
-{
- ///
- /// Provides signing and verifying operations using Azure Key Vault.
- ///
- public class KeyVaultSignatureProvider : SignatureProvider
- {
- private readonly HashAlgorithm _hash;
- private readonly IKeyVaultClient _client;
- private readonly KeyVaultSecurityKey _key;
- private bool _disposed = false;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The that will be used for signature operations.
- /// The signature algorithm to apply.
- /// Whether this is required to create signatures then set this to true.
- /// is null.
- /// is null or empty.
- public KeyVaultSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures)
- : this(key, algorithm, willCreateSignatures, null)
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The that will be used for signature operations.
- /// The signature algorithm to apply.
- /// Whether this is required to create signatures then set this to true.
- /// A mock used for testing purposes.
- internal KeyVaultSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures, IKeyVaultClient? client)
- : base(key, algorithm)
- {
- _key = key as KeyVaultSecurityKey ?? throw LogHelper.LogArgumentNullException(nameof(key));
- _client = client ?? new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(_key.Callback!));
- WillCreateSignatures = willCreateSignatures;
-
- switch (algorithm)
- {
- case SecurityAlgorithms.RsaSha256:
- _hash = SHA256.Create();
- break;
- case SecurityAlgorithms.RsaSha384:
- _hash = SHA384.Create();
- break;
- case SecurityAlgorithms.RsaSha512:
- _hash = SHA512.Create();
- break;
- default:
- throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10652, LogHelper.MarkAsNonPII(algorithm)), nameof(algorithm)));
- }
- }
-
- ///
- /// Produces a signature over the 'input' using Azure Key Vault.
- ///
- /// The bytes to sign.
- /// A signature over the input.
- /// if is null.
- /// if .Length == 0.
- /// If Dispose has been called.
- public override byte[] Sign(byte[] input)
- {
- return SignAsync(input, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult();
- }
-
- ///
- /// Verifies that the is over using Azure Key Vault.
- ///
- /// bytes to verify.
- /// signature to compare against.
- /// true if the computed signature matches the signature parameter, false otherwise.
- /// is null or has length == 0.
- /// is null or has length == 0.
- /// If Dispose has been called.
- public override bool Verify(byte[] input, byte[] signature)
- {
- return VerifyAsync(input, signature, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult();
- }
-
- ///
- public override bool Verify(byte[] input, int inputOffset, int lengthOffset, byte[] signature, int signatureOffset, int signatureLength) => throw new NotImplementedException();
-
- ///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///
- /// true, if called from Dispose(), false, if invoked inside a finalizer
- protected override void Dispose(bool disposing)
- {
- if (!_disposed)
- {
- if (disposing)
- {
- _disposed = true;
- _hash.Dispose();
- _client.Dispose();
- }
- }
- }
-
- ///
- /// Creates a digital signature using Azure Key Vault.
- ///
- /// bytes to sign.
- /// Propagates notification that operations should be canceled.
- /// A signature over the input.
- /// is null or has length == 0.
- /// If Dispose has been called.
- private async Task SignAsync(byte[] input, CancellationToken cancellation)
- {
- if (input == null || input.Length == 0)
- throw LogHelper.LogArgumentNullException(nameof(input));
-
- if (_disposed)
- throw LogHelper.LogExceptionMessage(new ObjectDisposedException(GetType().ToString()));
-
- return (await _client.SignAsync(_key.KeyId, Algorithm, _hash.ComputeHash(input), cancellation).ConfigureAwait(false)).Result;
- }
-
- ///
- /// Verifies a digital signature using Azure Key Vault.
- ///
- /// bytes to verify.
- /// signature to compare against.
- /// Propagates notification that operations should be canceled.
- /// true if the computed signature matches the signature parameter, false otherwise.
- /// is null or has length == 0.
- /// is null or has length == 0.
- /// If Dispose has been called.
- private async Task VerifyAsync(byte[] input, byte[] signature, CancellationToken cancellation)
- {
- if (input == null || input.Length == 0)
- throw LogHelper.LogArgumentNullException(nameof(input));
-
- if (signature == null || signature.Length == 0)
- throw LogHelper.LogArgumentNullException(nameof(signature));
-
- if (_disposed)
- throw LogHelper.LogExceptionMessage(new ObjectDisposedException(GetType().ToString()));
-
- return await _client.VerifyAsync(_key.KeyId, Algorithm, _hash.ComputeHash(input), signature, cancellation).ConfigureAwait(false);
- }
- }
-}
diff --git a/src/Microsoft.IdentityModel.KeyVaultExtensions/Microsoft.IdentityModel.KeyVaultExtensions.csproj b/src/Microsoft.IdentityModel.KeyVaultExtensions/Microsoft.IdentityModel.KeyVaultExtensions.csproj
deleted file mode 100644
index 2825f85730..0000000000
--- a/src/Microsoft.IdentityModel.KeyVaultExtensions/Microsoft.IdentityModel.KeyVaultExtensions.csproj
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
- Microsoft.IdentityModel.KeyVaultExtensions
- Includes types that provide support for signing and encrypting tokens with Azure Key Vault.
- true
- Microsoft.IdentityModel.KeyVaultExtensions
- netstandard2.0;net6.0;net8.0
- $(TargetFrameworks);net9.0
- .NET;Windows;Authentication;Identity;Azure;Key;Vault;Extensions
- enable
-
-
-
- full
- true
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
diff --git a/src/Microsoft.IdentityModel.KeyVaultExtensions/Properties/AssemblyInfo.cs b/src/Microsoft.IdentityModel.KeyVaultExtensions/Properties/AssemblyInfo.cs
deleted file mode 100644
index 1f06ec3782..0000000000
--- a/src/Microsoft.IdentityModel.KeyVaultExtensions/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyMetadata("Serviceable", "True")]
-[assembly: CLSCompliant(true)]
-[assembly: ComVisible(false)]
diff --git a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/GlobalSuppression.cs b/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/GlobalSuppression.cs
deleted file mode 100644
index 04498d0dc3..0000000000
--- a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/GlobalSuppression.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-// This file is used by Code Analysis to maintain SuppressMessage
-// attributes that are applied to this project.
-// Project-level suppressions either have no target or are given
-// a specific target and scoped to a namespace, type, member, etc.
-
-using System.Diagnostics.CodeAnalysis;
-
-[assembly: SuppressMessage("Naming", "CA1724:Type names should not match namespaces", Justification = "Previously released with this name", Scope ="Type", Target = "Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.ManagedKeyVaultSecurityKey")]
diff --git a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/InternalsVisibleTo.cs b/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/InternalsVisibleTo.cs
deleted file mode 100644
index cae70d8a10..0000000000
--- a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/InternalsVisibleTo.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.Tokens.Extensions.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
diff --git a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/ManagedKeyVaultSecurityKey.cs b/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/ManagedKeyVaultSecurityKey.cs
deleted file mode 100644
index 78ce01f9ee..0000000000
--- a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/ManagedKeyVaultSecurityKey.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using Microsoft.Azure.Services.AppAuthentication;
-using Microsoft.IdentityModel.Clients.ActiveDirectory;
-using Microsoft.IdentityModel.KeyVaultExtensions;
-using Microsoft.IdentityModel.Logging;
-using System;
-
-namespace Microsoft.IdentityModel.ManagedKeyVaultSecurityKey
-{
- ///
- /// Provides signing and verifying operations using Azure Key Vault
- /// for resources that are using Managed identities for Azure resources.
- ///
- public class ManagedKeyVaultSecurityKey : KeyVaultSecurityKey
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The key identifier that is recognized by KeyVault.
- /// if is null or empty.
- public ManagedKeyVaultSecurityKey(string keyIdentifier)
- : base(keyIdentifier, new AuthenticationCallback((new AzureServiceTokenProvider()).KeyVaultTokenCallback))
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The key identifier that is recognized by KeyVault.
- /// The authentication callback.
- /// if is null or empty.
- /// if is null.
- public ManagedKeyVaultSecurityKey(string keyIdentifier, AuthenticationCallback callback)
- : base(keyIdentifier, callback)
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The key identifier.
- /// Identifier of the client.
- /// Secret of the client identity.
- /// if is null or empty.
- /// if is null or empty.
- /// if is null or clientSecret.
- public ManagedKeyVaultSecurityKey(string keyIdentifier, string clientId, string clientSecret)
- {
- if (string.IsNullOrEmpty(keyIdentifier))
- throw LogHelper.LogArgumentNullException(nameof(keyIdentifier));
-
- if (string.IsNullOrEmpty(clientId))
- throw LogHelper.LogArgumentNullException(nameof(clientId));
-
- if (string.IsNullOrEmpty(clientSecret))
- throw LogHelper.LogArgumentNullException(nameof(clientSecret));
-
- KeyId = keyIdentifier;
- Callback = new AuthenticationCallback(async (string authority, string resource, string scope) =>
- (await (new AuthenticationContext(authority, TokenCache.DefaultShared)).AcquireTokenAsync(resource, new ClientCredential(clientId, clientSecret)).ConfigureAwait(false)).AccessToken);
- }
- }
-}
diff --git a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.csproj b/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.csproj
deleted file mode 100644
index aa342135ca..0000000000
--- a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.csproj
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
- Microsoft.IdentityModel.ManagedKeyVaultSecurityKey
- Includes types that provide support for signing and encrypting tokens with Azure Key Vault for
- Applications that are using Managed identities for Azure resources.
- true
- Microsoft.IdentityModel.ManagedKeyVaultSecurityKey
- netstandard2.0
- .NET;Windows;Authentication;Identity;Azure;Key;Vault;Extensions
- enable
-
-
-
- full
- true
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
diff --git a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Properties/AssemblyInfo.cs b/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Properties/AssemblyInfo.cs
deleted file mode 100644
index 1f06ec3782..0000000000
--- a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyMetadata("Serviceable", "True")]
-[assembly: CLSCompliant(true)]
-[assembly: ComVisible(false)]
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs
index 6ddc1b613d..36fb436a61 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs
@@ -28,6 +28,7 @@ public class OpenIdConnectConfiguration : BaseConfiguration
private ICollection _claimsSupported;
private ICollection _claimsLocalesSupported;
private ICollection _claimTypesSupported;
+ private ICollection _codeChallengeMethodsSupported;
private ICollection _displayValuesSupported;
private ICollection _dPoPSigningAlgValuesSupported;
private ICollection _grantTypesSupported;
@@ -42,6 +43,8 @@ public class OpenIdConnectConfiguration : BaseConfiguration
private ICollection _requestObjectSigningAlgValuesSupported;
private ICollection _responseModesSupported;
private ICollection _responseTypesSupported;
+ private ICollection _revocationEndpointAuthMethodsSupported;
+ private ICollection _revocationEndpointAuthSigningAlgValuesSupported;
private ICollection _scopesSupported;
private ICollection _subjectTypesSupported;
private ICollection _tokenEndpointAuthMethodsSupported;
@@ -233,6 +236,24 @@ public OpenIdConnectConfiguration(string json)
Interlocked.CompareExchange(ref _claimTypesSupported, new Collection(), null) ??
_claimTypesSupported;
+ ///
+ /// Gets the collection of 'code_challenge_methods_supported'
+ ///
+ [JsonPropertyName(OpenIdProviderMetadataNames.CodeChallengeMethodsSupported)]
+ public ICollection CodeChallengeMethodsSupported =>
+ _codeChallengeMethodsSupported ??
+ Interlocked.CompareExchange(ref _codeChallengeMethodsSupported, new Collection(), null) ??
+ _codeChallengeMethodsSupported;
+
+ ///
+ /// Gets or sets the 'device_authorization_endpoint'.
+ ///
+ [JsonPropertyName(OpenIdProviderMetadataNames.DeviceAuthorizationEndpoint)]
+#if NET6_0_OR_GREATER
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
+ public string DeviceAuthorizationEndpoint { get; set; }
+
///
/// Gets the collection of 'display_values_supported'
///
@@ -374,7 +395,7 @@ public OpenIdConnectConfiguration(string json)
/// Gets or sets the
///
[JsonIgnore]
- public JsonWebKeySet JsonWebKeySet {get; set;}
+ public JsonWebKeySet JsonWebKeySet { get; set; }
///
/// Boolean value specifying whether the OP can pass a sid (session ID) query parameter to identify the RP session at the OP when the logout_uri is used. Dafault Value is false.
@@ -508,6 +529,33 @@ public OpenIdConnectConfiguration(string json)
Interlocked.CompareExchange(ref _responseTypesSupported, new Collection(), null) ??
_responseTypesSupported;
+ ///
+ /// Gets or sets the 'revocation_endpoint'
+ ///
+ [JsonPropertyName(OpenIdProviderMetadataNames.RevocationEndpoint)]
+#if NET6_0_OR_GREATER
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
+ public string RevocationEndpoint { get; set; }
+
+ ///
+ /// Gets the collection of 'revocation_endpoint_auth_methods_supported'.
+ ///
+ [JsonPropertyName(OpenIdProviderMetadataNames.RevocationEndpointAuthMethodsSupported)]
+ public ICollection RevocationEndpointAuthMethodsSupported =>
+ _revocationEndpointAuthMethodsSupported ??
+ Interlocked.CompareExchange(ref _revocationEndpointAuthMethodsSupported, new Collection(), null) ??
+ _revocationEndpointAuthMethodsSupported;
+
+ ///
+ /// Gets the collection of 'revocation_endpoint_auth_signing_alg_values_supported'.
+ ///
+ [JsonPropertyName(OpenIdProviderMetadataNames.RevocationEndpointAuthSigningAlgValuesSupported)]
+ public ICollection RevocationEndpointAuthSigningAlgValuesSupported =>
+ _revocationEndpointAuthSigningAlgValuesSupported ??
+ Interlocked.CompareExchange(ref _revocationEndpointAuthSigningAlgValuesSupported, new Collection(), null) ??
+ _revocationEndpointAuthSigningAlgValuesSupported;
+
///
/// Gets or sets the 'service_documentation'
///
@@ -688,6 +736,17 @@ public bool ShouldSerializeClaimTypesSupported()
return ClaimTypesSupported.Count > 0;
}
+ ///
+ /// Gets a bool that determines if the 'code_challenge_methods_supported' (CodeChallengeMethodsSupported) property should be serialized.
+ /// This is used by Json.NET in order to conditionally serialize properties.
+ ///
+ /// true if 'code_challenge_methods_supported' (CodeChallengeMethodsSupported) is not empty; otherwise, false.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool ShouldSerializeCodeChallengeMethodsSupported()
+ {
+ return CodeChallengeMethodsSupported.Count > 0;
+ }
+
///
/// Gets a bool that determines if the 'display_values_supported' (DisplayValuesSupported) property should be serialized.
/// This is used by Json.NET in order to conditionally serialize properties.
@@ -842,6 +901,28 @@ public bool ShouldSerializeResponseTypesSupported()
return ResponseTypesSupported.Count > 0;
}
+ ///
+ /// Gets a bool that determines if the 'revocation_endpoint_auth_methods_supported' (RevocationEndpointAuthMethodsSupported) property should be serialized.
+ /// This is used by Json.NET in order to conditionally serialize properties.
+ ///
+ /// true if 'revocation_endpoint_auth_methods_supported' (RevocationEndpointAuthMethodsSupported) is not empty; otherwise, false.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool ShouldSerializeRevocationEndpointAuthMethodsSupported()
+ {
+ return RevocationEndpointAuthMethodsSupported.Count > 0;
+ }
+
+ ///
+ /// Gets a bool that determines if the 'revocation_endpoint_auth_signing_alg_values_supported' (RevocationEndpointAuthSigningAlgValuesSupported) property should be serialized.
+ /// This is used by Json.NET in order to conditionally serialize properties.
+ ///
+ /// true if 'revocation_endpoint_auth_signing_alg_values_supported' (RevocationEndpointAuthSigningAlgValuesSupported) is not empty; otherwise, false.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool ShouldSerializeRevocationEndpointAuthSigningAlgValuesSupported()
+ {
+ return RevocationEndpointAuthSigningAlgValuesSupported.Count > 0;
+ }
+
///
/// Gets a bool that determines if the 'SigningKeys' property should be serialized.
/// This is used by Json.NET in order to conditionally serialize properties.
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfigurationRetriever.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfigurationRetriever.cs
index 17b354b390..d8d0c9d37b 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfigurationRetriever.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfigurationRetriever.cs
@@ -10,13 +10,11 @@
namespace Microsoft.IdentityModel.Protocols.OpenIdConnect
{
-
///
/// Retrieves a populated given an address.
///
public class OpenIdConnectConfigurationRetriever : IConfigurationRetriever
{
-
///
/// Retrieves a populated given an address.
///
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Exceptions/OpenIdConnectProtocolException.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Exceptions/OpenIdConnectProtocolException.cs
index 1cc301ed01..91585f9573 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Exceptions/OpenIdConnectProtocolException.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Exceptions/OpenIdConnectProtocolException.cs
@@ -6,7 +6,6 @@
namespace Microsoft.IdentityModel.Protocols.OpenIdConnect
{
-
///
/// This exception is thrown when an OpenIdConnect protocol handler encounters a protocol error.
///
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs
index fc877effad..9e99a0899d 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs
@@ -3,6 +3,9 @@
// See the LICENSE file in the project root for more information.
using System;
+#if NET8_0_OR_GREATER
+using System.Collections.Frozen;
+#endif
using System.Collections.Generic;
using System.IO;
using System.Text;
@@ -26,7 +29,13 @@ internal static class OpenIdConnectConfigurationSerializer
// If not found, then we assume we should put the value into AdditionalData.
// If we didn't do that, we would pay a performance penalty for those cases where there is AdditionalData
// but otherwise the JSON properties are all lower case.
- public static HashSet OpenIdProviderMetadataNamesUpperCase = new HashSet
+ public static readonly
+#if NET8_0_OR_GREATER
+ FrozenSet
+#else
+ HashSet
+#endif
+ OpenIdProviderMetadataNamesUpperCase = new HashSet
{
"ACR_VALUES_SUPPORTED",
"AUTHORIZATION_ENDPOINT",
@@ -40,7 +49,9 @@ internal static class OpenIdConnectConfigurationSerializer
"CLAIMS_PARAMETER_SUPPORTED",
"CLAIMS_SUPPORTED",
"CLAIM_TYPES_SUPPORTED",
+ "CODE_CHALLENGE_METHODS_SUPPORTED",
".WELL-KNOWN/OPENID-CONFIGURATION",
+ "DEVICE_AUTHORIZATION_ENDPOINT",
"DISPLAY_VALUES_SUPPORTED",
"DPOP_SIGNING_ALG_VALUES_SUPPORTED",
"END_SESSION_ENDPOINT",
@@ -71,6 +82,9 @@ internal static class OpenIdConnectConfigurationSerializer
"REQUIRE_REQUEST_URI_REGISTRATION",
"RESPONSE_MODES_SUPPORTED",
"RESPONSE_TYPES_SUPPORTED",
+ "REVOCATION_ENDPOINT",
+ "REVOCATION_ENDPOINT_AUTH_METHODS_SUPPORTED",
+ "REVOCATION_ENDPOINT_AUTH_SIGNING_ALG_VALUES_SUPPORTED",
"SERVICE_DOCUMENTATION",
"SCOPES_SUPPORTED",
"SUBJECT_TYPES_SUPPORTED",
@@ -82,7 +96,11 @@ internal static class OpenIdConnectConfigurationSerializer
"USERINFO_ENCRYPTION_ALG_VALUES_SUPPORTED",
"USERINFO_ENCRYPTION_ENC_VALUES_SUPPORTED",
"USERINFO_SIGNING_ALG_VALUES_SUPPORTED",
- };
+ }
+#if NET8_0_OR_GREATER
+ .ToFrozenSet()
+#endif
+ ;
#region Read
public static OpenIdConnectConfiguration Read(string json)
@@ -97,7 +115,7 @@ public static OpenIdConnectConfiguration Read(string json, OpenIdConnectConfigur
{
return Read(ref reader, config);
}
- catch(JsonException ex)
+ catch (JsonException ex)
{
if (ex.GetType() == typeof(JsonException))
throw;
@@ -131,7 +149,7 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC
LogHelper.MarkAsNonPII(reader.CurrentDepth),
LogHelper.MarkAsNonPII(reader.BytesConsumed))));
- while(true)
+ while (true)
{
#region Check property name using ValueTextEquals
// https://datatracker.ietf.org/doc/html/rfc7517#section-4, does not require that we reject JSON with duplicate member names.
@@ -174,6 +192,12 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC
else if (reader.ValueTextEquals(Utf8Bytes.ClaimTypesSupported))
JsonPrimitives.ReadStrings(ref reader, config.ClaimTypesSupported, MetadataName.ClaimTypesSupported, ClassName, true);
+ else if (reader.ValueTextEquals(Utf8Bytes.CodeChallengeMethodsSupported))
+ JsonPrimitives.ReadStrings(ref reader, config.CodeChallengeMethodsSupported, MetadataName.CodeChallengeMethodsSupported, ClassName, true);
+
+ else if (reader.ValueTextEquals(Utf8Bytes.DeviceAuthorizationEndpoint))
+ config.DeviceAuthorizationEndpoint = JsonPrimitives.ReadString(ref reader, MetadataName.DeviceAuthorizationEndpoint, ClassName, true);
+
else if (reader.ValueTextEquals(Utf8Bytes.DisplayValuesSupported))
JsonPrimitives.ReadStrings(ref reader, config.DisplayValuesSupported, MetadataName.DisplayValuesSupported, ClassName, true);
@@ -277,14 +301,20 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC
else if (reader.ValueTextEquals(Utf8Bytes.ResponseTypesSupported))
JsonPrimitives.ReadStrings(ref reader, config.ResponseTypesSupported, MetadataName.ResponseTypesSupported, ClassName, true);
- else if (reader.ValueTextEquals(Utf8Bytes.ScopesSupported))
- JsonPrimitives.ReadStrings(ref reader, config.ScopesSupported, MetadataName.ScopesSupported, ClassName, true);
+ else if (reader.ValueTextEquals(Utf8Bytes.RevocationEndpoint))
+ config.RevocationEndpoint = JsonPrimitives.ReadString(ref reader, MetadataName.RevocationEndpoint, ClassName, true);
+
+ else if (reader.ValueTextEquals(Utf8Bytes.RevocationEndpointAuthMethodsSupported))
+ JsonPrimitives.ReadStrings(ref reader, config.RevocationEndpointAuthMethodsSupported, MetadataName.RevocationEndpointAuthMethodsSupported, ClassName, true);
+
+ else if (reader.ValueTextEquals(Utf8Bytes.RevocationEndpointAuthSigningAlgValuesSupported))
+ JsonPrimitives.ReadStrings(ref reader, config.RevocationEndpointAuthSigningAlgValuesSupported, MetadataName.RevocationEndpointAuthSigningAlgValuesSupported, ClassName, true);
else if (reader.ValueTextEquals(Utf8Bytes.ServiceDocumentation))
- config.ServiceDocumentation = JsonPrimitives.ReadString(ref reader, MetadataName.ScopesSupported, ClassName, true);
+ config.ServiceDocumentation = JsonPrimitives.ReadString(ref reader, MetadataName.ServiceDocumentation, ClassName, true);
- else if (reader.ValueTextEquals(Utf8Bytes.SubjectTypesSupported))
- JsonPrimitives.ReadStrings(ref reader, config.SubjectTypesSupported, MetadataName.SubjectTypesSupported, ClassName, true);
+ else if (reader.ValueTextEquals(Utf8Bytes.ScopesSupported))
+ JsonPrimitives.ReadStrings(ref reader, config.ScopesSupported, MetadataName.ScopesSupported, ClassName, true);
else if (reader.ValueTextEquals(Utf8Bytes.SubjectTypesSupported))
JsonPrimitives.ReadStrings(ref reader, config.SubjectTypesSupported, MetadataName.SubjectTypesSupported, ClassName, true);
@@ -366,6 +396,12 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC
else if (propertyName.Equals(MetadataName.ClaimTypesSupported, StringComparison.OrdinalIgnoreCase))
JsonPrimitives.ReadStrings(ref reader, config.ClaimTypesSupported, propertyName, ClassName);
+ else if (propertyName.Equals(MetadataName.CodeChallengeMethodsSupported, StringComparison.OrdinalIgnoreCase))
+ JsonPrimitives.ReadStrings(ref reader, config.CodeChallengeMethodsSupported, propertyName, ClassName);
+
+ else if (propertyName.Equals(MetadataName.DeviceAuthorizationEndpoint, StringComparison.OrdinalIgnoreCase))
+ config.DeviceAuthorizationEndpoint = JsonPrimitives.ReadString(ref reader, propertyName, ClassName);
+
else if (propertyName.Equals(MetadataName.DisplayValuesSupported, StringComparison.OrdinalIgnoreCase))
JsonPrimitives.ReadStrings(ref reader, config.DisplayValuesSupported, propertyName, ClassName);
@@ -407,7 +443,7 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC
else if (propertyName.Equals(MetadataName.IdTokenEncryptionEncValuesSupported, StringComparison.OrdinalIgnoreCase))
JsonPrimitives.ReadStrings(ref reader, config.IdTokenEncryptionEncValuesSupported, propertyName, ClassName);
- else if (propertyName.Equals(MetadataName.IdTokenSigningAlgValuesSupported , StringComparison.OrdinalIgnoreCase))
+ else if (propertyName.Equals(MetadataName.IdTokenSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase))
JsonPrimitives.ReadStrings(ref reader, config.IdTokenSigningAlgValuesSupported, propertyName, ClassName);
else if (propertyName.Equals(MetadataName.IntrospectionEndpoint, StringComparison.OrdinalIgnoreCase))
@@ -470,6 +506,15 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC
else if (propertyName.Equals(MetadataName.ResponseTypesSupported, StringComparison.OrdinalIgnoreCase))
JsonPrimitives.ReadStrings(ref reader, config.ResponseTypesSupported, propertyName, ClassName);
+ else if (propertyName.Equals(MetadataName.RevocationEndpoint, StringComparison.OrdinalIgnoreCase))
+ config.RevocationEndpoint = JsonPrimitives.ReadString(ref reader, propertyName, ClassName);
+
+ else if (propertyName.Equals(MetadataName.RevocationEndpointAuthMethodsSupported, StringComparison.OrdinalIgnoreCase))
+ JsonPrimitives.ReadStrings(ref reader, config.RevocationEndpointAuthMethodsSupported, propertyName, ClassName);
+
+ else if (propertyName.Equals(MetadataName.RevocationEndpointAuthSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase))
+ JsonPrimitives.ReadStrings(ref reader, config.RevocationEndpointAuthSigningAlgValuesSupported, propertyName, ClassName);
+
else if (propertyName.Equals(MetadataName.ScopesSupported, StringComparison.OrdinalIgnoreCase))
JsonPrimitives.ReadStrings(ref reader, config.ScopesSupported, propertyName, ClassName);
@@ -577,6 +622,12 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c
if (config.ClaimTypesSupported.Count > 0)
JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.ClaimTypesSupported, config.ClaimTypesSupported);
+ if (config.CodeChallengeMethodsSupported.Count > 0)
+ JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.CodeChallengeMethodsSupported, config.CodeChallengeMethodsSupported);
+
+ if (!string.IsNullOrEmpty(config.DeviceAuthorizationEndpoint))
+ writer.WriteString(Utf8Bytes.DeviceAuthorizationEndpoint, config.DeviceAuthorizationEndpoint);
+
if (config.DisplayValuesSupported.Count > 0)
JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.DisplayValuesSupported, config.DisplayValuesSupported);
@@ -638,7 +689,7 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c
writer.WriteString(Utf8Bytes.PushedAuthorizationRequestEndpoint, config.PushedAuthorizationRequestEndpoint);
if (!string.IsNullOrEmpty(config.RegistrationEndpoint))
- writer.WriteString(Utf8Bytes.RegistrationEndpoint, config.RegistrationEndpoint);
+ writer.WriteString(Utf8Bytes.RegistrationEndpoint, config.RegistrationEndpoint);
if (config.RequestObjectEncryptionAlgValuesSupported.Count > 0)
JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.RequestObjectEncryptionAlgValuesSupported, config.RequestObjectEncryptionAlgValuesSupported);
@@ -670,6 +721,15 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c
if (config.ScopesSupported.Count > 0)
JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.ScopesSupported, config.ScopesSupported);
+ if (!string.IsNullOrEmpty(config.RevocationEndpoint))
+ writer.WriteString(Utf8Bytes.RevocationEndpoint, config.RevocationEndpoint);
+
+ if (config.RevocationEndpointAuthMethodsSupported.Count > 0)
+ JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.RevocationEndpointAuthMethodsSupported, config.RevocationEndpointAuthMethodsSupported);
+
+ if (config.RevocationEndpointAuthSigningAlgValuesSupported.Count > 0)
+ JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.RevocationEndpointAuthSigningAlgValuesSupported, config.RevocationEndpointAuthSigningAlgValuesSupported);
+
if (!string.IsNullOrEmpty(config.ServiceDocumentation))
writer.WriteString(Utf8Bytes.ServiceDocumentation, config.ServiceDocumentation);
@@ -708,4 +768,3 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c
#endregion
}
}
-
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdProviderMetadataNames.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdProviderMetadataNames.cs
index 554f81a0f7..62f15637c6 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdProviderMetadataNames.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdProviderMetadataNames.cs
@@ -24,6 +24,8 @@ public static class OpenIdProviderMetadataNames
public const string ClaimsParameterSupported = "claims_parameter_supported";
public const string ClaimsSupported = "claims_supported";
public const string ClaimTypesSupported = "claim_types_supported";
+ public const string CodeChallengeMethodsSupported = "code_challenge_methods_supported";
+ public const string DeviceAuthorizationEndpoint = "device_authorization_endpoint";
public const string Discovery = ".well-known/openid-configuration";
public const string DisplayValuesSupported = "display_values_supported";
public const string DPoPSigningAlgValuesSupported = "dpop_signing_alg_values_supported";
@@ -56,6 +58,9 @@ public static class OpenIdProviderMetadataNames
public const string RequireRequestUriRegistration = "require_request_uri_registration";
public const string ResponseModesSupported = "response_modes_supported";
public const string ResponseTypesSupported = "response_types_supported";
+ public const string RevocationEndpoint = "revocation_endpoint";
+ public const string RevocationEndpointAuthMethodsSupported = "revocation_endpoint_auth_methods_supported";
+ public const string RevocationEndpointAuthSigningAlgValuesSupported = "revocation_endpoint_auth_signing_alg_values_supported";
public const string ServiceDocumentation = "service_documentation";
public const string ScopesSupported = "scopes_supported";
public const string SubjectTypesSupported = "subject_types_supported";
@@ -89,6 +94,8 @@ internal static class OpenIdProviderMetadataUtf8Bytes
public static ReadOnlySpan ClaimsParameterSupported => "claims_parameter_supported"u8;
public static ReadOnlySpan ClaimsSupported => "claims_supported"u8;
public static ReadOnlySpan ClaimTypesSupported => "claim_types_supported"u8;
+ public static ReadOnlySpan CodeChallengeMethodsSupported => "code_challenge_methods_supported"u8;
+ public static ReadOnlySpan DeviceAuthorizationEndpoint => "device_authorization_endpoint"u8;
public static ReadOnlySpan Discovery => ".well-known/openid-configuration"u8;
public static ReadOnlySpan DisplayValuesSupported => "display_values_supported"u8;
public static ReadOnlySpan DPoPSigningAlgValuesSupported => "dpop_signing_alg_values_supported"u8;
@@ -121,6 +128,9 @@ internal static class OpenIdProviderMetadataUtf8Bytes
public static ReadOnlySpan RequireRequestUriRegistration => "require_request_uri_registration"u8;
public static ReadOnlySpan ResponseModesSupported => "response_modes_supported"u8;
public static ReadOnlySpan ResponseTypesSupported => "response_types_supported"u8;
+ public static ReadOnlySpan RevocationEndpoint => "revocation_endpoint"u8;
+ public static ReadOnlySpan RevocationEndpointAuthMethodsSupported => "revocation_endpoint_auth_methods_supported"u8;
+ public static ReadOnlySpan RevocationEndpointAuthSigningAlgValuesSupported => "revocation_endpoint_auth_signing_alg_values_supported"u8;
public static ReadOnlySpan ServiceDocumentation => "service_documentation"u8;
public static ReadOnlySpan ScopesSupported => "scopes_supported"u8;
public static ReadOnlySpan SubjectTypesSupported => "subject_types_supported"u8;
diff --git a/src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs b/src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs
index e75bc6aa1a..349e9b51bb 100644
--- a/src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs
@@ -199,14 +199,9 @@ private void InitializeUsingRsa(RSA rsa, string algorithm)
RSASignaturePadding = RSASignaturePadding.Pkcs1;
}
- RSAEncryptionPadding = algorithm switch
- {
- SecurityAlgorithms.RsaOAEP => RSAEncryptionPadding.OaepSHA1,
- SecurityAlgorithms.RsaOaepKeyWrap => RSAEncryptionPadding.OaepSHA1,
- SecurityAlgorithms.RsaOAEP256 => RSAEncryptionPadding.OaepSHA256,
- _ => RSAEncryptionPadding.Pkcs1
- };
-
+ RSAEncryptionPadding = (algorithm.Equals(SecurityAlgorithms.RsaOAEP) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap))
+ ? RSAEncryptionPadding.OaepSHA1
+ : RSAEncryptionPadding.Pkcs1;
RSA = rsa;
_decryptFunction = DecryptWithRsa;
_encryptFunction = EncryptWithRsa;
diff --git a/src/Microsoft.IdentityModel.Tokens/Exceptions/SecurityTokenException.cs b/src/Microsoft.IdentityModel.Tokens/Exceptions/SecurityTokenException.cs
index f544c99e93..e346c7cf73 100644
--- a/src/Microsoft.IdentityModel.Tokens/Exceptions/SecurityTokenException.cs
+++ b/src/Microsoft.IdentityModel.Tokens/Exceptions/SecurityTokenException.cs
@@ -2,18 +2,22 @@
// Licensed under the MIT License.
using System;
+using System.Diagnostics;
using System.Runtime.Serialization;
+using System.Text;
using Microsoft.IdentityModel.Logging;
namespace Microsoft.IdentityModel.Tokens
{
-
///
/// Represents a security token exception.
///
[Serializable]
public class SecurityTokenException : Exception
{
+ [NonSerialized]
+ private string _stackTrace;
+
///
/// Initializes a new instance of the class.
///
@@ -55,6 +59,49 @@ protected SecurityTokenException(SerializationInfo info, StreamingContext contex
{
}
+ ///
+ /// Gets the stack trace that is captured when the exception is created.
+ ///
+ public override string StackTrace
+ {
+ get
+ {
+ if (_stackTrace == null)
+ {
+ if (ExceptionDetail == null)
+ return base.StackTrace;
+#if NET8_0_OR_GREATER
+ _stackTrace = new StackTrace(ExceptionDetail.StackFrames).ToString();
+#else
+ StringBuilder sb = new();
+ foreach (StackFrame frame in ExceptionDetail.StackFrames)
+ {
+ sb.Append(frame.ToString());
+ sb.Append(Environment.NewLine);
+ }
+
+ _stackTrace = sb.ToString();
+#endif
+ }
+
+ return _stackTrace;
+ }
+ }
+
+ ///
+ /// Gets or sets the source of the exception.
+ ///
+ public override string Source
+ {
+ get => base.Source;
+ set => base.Source = value;
+ }
+
+ internal ExceptionDetail ExceptionDetail
+ {
+ get; set;
+ }
+
#if NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
///
/// When overridden in a derived class, sets the System.Runtime.Serialization.SerializationInfo
diff --git a/src/Microsoft.IdentityModel.Tokens/InternalsVisibleTo.cs b/src/Microsoft.IdentityModel.Tokens/InternalsVisibleTo.cs
index ba34f3462b..dd03b90595 100644
--- a/src/Microsoft.IdentityModel.Tokens/InternalsVisibleTo.cs
+++ b/src/Microsoft.IdentityModel.Tokens/InternalsVisibleTo.cs
@@ -1,14 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.KeyVaultExtensions, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
-[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.TestUtils, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("CrossVersionTokenValidation.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.Tokens.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.JsonWebTokens, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.JsonWebTokens.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.Protocols.OpenIdConnect, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.TestUtils, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.IdentityModel.Tokens.Jwt, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.IdentityModel.Tokens.Jwt.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.IdentityModel.S2S, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
diff --git a/src/Microsoft.IdentityModel.Tokens/Json/JsonWebKeySerializer.cs b/src/Microsoft.IdentityModel.Tokens/Json/JsonWebKeySerializer.cs
index ef28e1cf5c..89defe3734 100644
--- a/src/Microsoft.IdentityModel.Tokens/Json/JsonWebKeySerializer.cs
+++ b/src/Microsoft.IdentityModel.Tokens/Json/JsonWebKeySerializer.cs
@@ -3,6 +3,9 @@
// See the LICENSE file in the project root for more information.
using System;
+#if NET8_0_OR_GREATER
+using System.Collections.Frozen;
+#endif
using System.Collections.Generic;
using System.IO;
using System.Text;
@@ -21,7 +24,13 @@ internal static class JsonWebKeySerializer
// If not found, then we assume we should put the value into AdditionalData.
// If we didn't do that, we would pay a performance penalty for those cases where there is AdditionalData
// but otherwise the JSON properties are all lower case.
- public static HashSet JsonWebKeyParameterNamesUpperCase = new HashSet
+ public static readonly
+#if NET8_0_OR_GREATER
+ FrozenSet
+#else
+ HashSet
+# endif
+ JsonWebKeyParameterNamesUpperCase = new HashSet
{
"ALG",
"CRV",
@@ -46,7 +55,11 @@ internal static class JsonWebKeySerializer
"X5T#S256",
"X5U",
"Y"
- };
+ }
+#if NET8_0_OR_GREATER
+ .ToFrozenSet()
+#endif
+ ;
#region Read
public static JsonWebKey Read(string json)
@@ -399,4 +412,3 @@ public static void Write(ref Utf8JsonWriter writer, JsonWebKey jsonWebKey)
#endregion
}
}
-
diff --git a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs
index b9fe6c2996..679fbf2b8f 100644
--- a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs
+++ b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs
@@ -35,7 +35,7 @@ internal static class LogMessages
public const string IDX10207 = "IDX10207: Unable to validate audience. The 'audiences' parameter is null.";
public const string IDX10208 = "IDX10208: Unable to validate audience. validationParameters.ValidAudience is null or whitespace and validationParameters.ValidAudiences is null.";
public const string IDX10209 = "IDX10209: Token has length: '{0}' which is larger than the MaximumTokenSizeInBytes: '{1}'.";
- public const string IDX10211 = "IDX10211: Unable to validate issuer. The 'issuer' parameter is null or whitespace";
+ public const string IDX10211 = "IDX10211: Unable to validate issuer. The 'issuer' parameter is null or whitespace.";
public const string IDX10214 = "IDX10214: Audience validation failed. Audiences: '{0}'. Did not match: validationParameters.ValidAudience: '{1}' or validationParameters.ValidAudiences: '{2}'.";
public const string IDX10222 = "IDX10222: Lifetime validation failed. The token is not yet valid. ValidFrom (UTC): '{0}', Current time (UTC): '{1}'.";
public const string IDX10223 = "IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '{0}', Current time (UTC): '{1}'.";
@@ -79,6 +79,8 @@ internal static class LogMessages
//public const string IDX10263 = "IDX10263: Unable to re-validate with ConfigurationManager.LastKnownGoodConfiguration as it is expired.";
public const string IDX10264 = "IDX10264: Reading issuer signing keys from validation parameters and configuration.";
public const string IDX10265 = "IDX10265: Reading issuer signing keys from configuration.";
+ //public const string IDX10266 = "IDX10266: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace, validationParameters.ValidIssuers is null or empty and ConfigurationManager is null.";
+
// 10500 - SignatureValidation
public const string IDX10500 = "IDX10500: Signature validation failed. No security keys were provided to validate the signature.";
diff --git a/src/Microsoft.IdentityModel.Tokens/Properties/AssemblyInfo.cs b/src/Microsoft.IdentityModel.Tokens/Properties/AssemblyInfo.cs
index f22a0f4b5e..12d7bcb55f 100644
--- a/src/Microsoft.IdentityModel.Tokens/Properties/AssemblyInfo.cs
+++ b/src/Microsoft.IdentityModel.Tokens/Properties/AssemblyInfo.cs
@@ -17,7 +17,6 @@
[assembly: InternalsVisibleTo("Microsoft.IdentityModel.Tokens.Saml, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: InternalsVisibleTo("Microsoft.IdentityModel.Xml, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: InternalsVisibleTo("Microsoft.AzureAD.SmartSessionEvaluator, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
-[assembly: InternalsVisibleTo("Microsoft.IdentityModel.KeyVaultExtensions.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: InternalsVisibleTo("Microsoft.IdentityModel.Protocols, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: InternalsVisibleTo("Microsoft.IdentityModel.Protocols.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: InternalsVisibleTo("Microsoft.IdentityModel.Validators, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
diff --git a/src/Microsoft.IdentityModel.Tokens/SecurityAlgorithms.cs b/src/Microsoft.IdentityModel.Tokens/SecurityAlgorithms.cs
index 16bee7667c..3db07ff95e 100644
--- a/src/Microsoft.IdentityModel.Tokens/SecurityAlgorithms.cs
+++ b/src/Microsoft.IdentityModel.Tokens/SecurityAlgorithms.cs
@@ -31,7 +31,6 @@ public static class SecurityAlgorithms
public const string Aes256KW = "A256KW";
public const string RsaPKCS1 = "RSA1_5";
public const string RsaOAEP = "RSA-OAEP";
- public const string RsaOAEP256 = "RSA-OAEP-256";
// See: https://www.w3.org/TR/xmlenc-core1/#sec-Exclusive-Canonicalization
public const string ExclusiveC14n = "http://www.w3.org/2001/10/xml-exc-c14n#";
diff --git a/src/Microsoft.IdentityModel.Tokens/SupportedAlgorithms.cs b/src/Microsoft.IdentityModel.Tokens/SupportedAlgorithms.cs
index dfd2416db7..086374360a 100644
--- a/src/Microsoft.IdentityModel.Tokens/SupportedAlgorithms.cs
+++ b/src/Microsoft.IdentityModel.Tokens/SupportedAlgorithms.cs
@@ -40,7 +40,6 @@ internal static class SupportedAlgorithms
internal static readonly ICollection RsaEncryptionAlgorithms = new Collection
{
SecurityAlgorithms.RsaOAEP,
- SecurityAlgorithms.RsaOAEP256,
SecurityAlgorithms.RsaPKCS1,
SecurityAlgorithms.RsaOaepKeyWrap
};
diff --git a/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs b/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs
index bb68764a6d..2112772699 100644
--- a/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs
+++ b/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs
@@ -13,7 +13,7 @@ namespace Microsoft.IdentityModel.Tokens
///
/// Contains a set of parameters that are used by a when validating a .
///
- public class TokenValidationParameters
+ public partial class TokenValidationParameters
{
private string _authenticationType;
private TimeSpan _clockSkew = DefaultClockSkew;
@@ -38,7 +38,7 @@ public class TokenValidationParameters
/// Default for the maximum token size.
///
/// 250 KB (kilobytes).
- public const Int32 DefaultMaximumTokenSizeInBytes = 1024 * 250;
+ public const int DefaultMaximumTokenSizeInBytes = 1024 * 250;
///
/// Copy constructor for .
@@ -66,6 +66,7 @@ protected TokenValidationParameters(TokenValidationParameters other)
IssuerSigningKeyValidatorUsingConfiguration = other.IssuerSigningKeyValidatorUsingConfiguration;
IssuerValidator = other.IssuerValidator;
IssuerValidatorAsync = other.IssuerValidatorAsync;
+ IssuerValidationDelegateAsync = other.IssuerValidationDelegateAsync;
IssuerValidatorUsingConfiguration = other.IssuerValidatorUsingConfiguration;
LifetimeValidator = other.LifetimeValidator;
LogTokenId = other.LogTokenId;
@@ -172,22 +173,6 @@ public string AuthenticationType
}
}
- /////
- ///// Gets or sets the for validating X509Certificate2(s).
- /////
- //public X509CertificateValidator CertificateValidator
- //{
- // get
- // {
- // return _certificateValidator;
- // }
-
- // set
- // {
- // _certificateValidator = value;
- // }
- //}
-
///
/// Gets or sets the clock skew to apply when validating a time.
///
@@ -368,7 +353,6 @@ public virtual ClaimsIdentity CreateClaimsIdentity(SecurityToken securityToken,
///
public IssuerValidator IssuerValidator { get; set; }
-
///
/// Gets or sets a delegate that will be used to validate the issuer of the token.
///
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/AsyncValidate.cd b/src/Microsoft.IdentityModel.Tokens/Validation/AsyncValidate.cd
new file mode 100644
index 0000000000..ebefb90859
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/AsyncValidate.cd
@@ -0,0 +1,81 @@
+
+
+
+
+
+ ABEAIAABEEAAEAIAAAAAAAABEQAAAEEACABAAAAkIoA=
+ Validation\TokenValidationResult.cs
+
+
+
+
+
+ AAEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA=
+ Validation\IssuerValidationResult.cs
+
+
+
+
+
+ AAAEAAAAAAAAAAAAAAAAEAAEAAAAAAAAAEAABAAAAAA=
+ Validation\ExceptionDetail.cs
+
+
+
+
+
+
+
+
+ AIAAAAJAAAAAAAAAAAgAIAABAAgAAAAABEBBAAAAAAA=
+ Validation\ValidationResult.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAA=
+ Validation\LogDetail.cs
+
+
+
+
+
+
+
+
+
+
+
+ AAAIAAAAAAAAAAAAAAIAAAQAAABAQAAAAAAAAAAAAAA=
+ Validation\ValidationFailureType.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAEIAAIAAAAAA=
+ Validation\MessageDetail.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ CallContext.cs
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/ExceptionDetail.cs b/src/Microsoft.IdentityModel.Tokens/Validation/ExceptionDetail.cs
new file mode 100644
index 0000000000..1ab311c9e8
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/ExceptionDetail.cs
@@ -0,0 +1,73 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// Contains information so that Exceptions can be logged or thrown written as required.
+ ///
+ internal class ExceptionDetail
+ {
+ ///
+ /// Creates an instance of
+ ///
+ /// contains information about the exception that is used to generate the exception message.
+ /// is the type of exception that occurred.
+ /// contains information about the stack frame where the exception occurred.
+ public ExceptionDetail(MessageDetail messageDetail, Type exceptionType, StackFrame stackFrame)
+ : this(messageDetail, exceptionType, stackFrame, null)
+ {
+ }
+
+ ///
+ /// Creates an instance of
+ ///
+ /// contains information about the exception that is used to generate the exception message.
+ /// is the type of exception that occurred.
+ /// contains information about the stack frame where the exception occurred.
+ /// is the inner exception that occurred.
+ public ExceptionDetail(MessageDetail messageDetail, Type exceptionType, StackFrame stackFrame, Exception innerException)
+ {
+ ExceptionType = exceptionType;
+ InnerException = innerException;
+ MessageDetail = messageDetail;
+ StackFrames.Add(stackFrame);
+ }
+
+ ///
+ /// Creates an instance of an using
+ ///
+ /// An instantance of an Exception.
+ public Exception GetException()
+ {
+ if (InnerException != null)
+ return Activator.CreateInstance(ExceptionType, MessageDetail.Message, InnerException) as Exception;
+
+ return Activator.CreateInstance(ExceptionType, MessageDetail.Message) as Exception;
+ }
+
+ ///
+ /// Gets the type of exception that occurred.
+ ///
+ public Type ExceptionType { get; }
+
+ ///
+ /// Gets the inner exception that occurred.
+ ///
+ public Exception InnerException { get; }
+
+ ///
+ /// Gets the message details that are used to generate the exception message.
+ ///
+ public MessageDetail MessageDetail { get; }
+
+ ///
+ /// Gets the stack frames where the exception occurred.
+ ///
+ public IList StackFrames { get; } = [];
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Exceptions.cd b/src/Microsoft.IdentityModel.Tokens/Validation/Exceptions.cd
new file mode 100644
index 0000000000..cd69bb66db
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/Exceptions.cd
@@ -0,0 +1,35 @@
+
+
+
+
+
+ AIAAAAAAAgAAAgAAAAQAAAAAAAAAAAAAAAAAAAAAAAA=
+ Exceptions\SecurityTokenException.cs
+
+
+
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Exceptions\SecurityTokenValidationException.cs
+
+
+
+
+
+ AAgAAEAAAAAAAAAAAAACAAAgAAAAAAAAAAAAAAAAAAA=
+ Exceptions\SecurityTokenInvalidIssuerException.cs
+
+
+
+
+
+ AAAEAAAAAAAAAAAAAAAAEAAEAAAAAAAAAEAABAAAAAA=
+ Validation\ExceptionDetail.cs
+
+
+
+
\ No newline at end of file
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/IssuerValidationResult.cs b/src/Microsoft.IdentityModel.Tokens/Validation/IssuerValidationResult.cs
new file mode 100644
index 0000000000..35c53dc561
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/IssuerValidationResult.cs
@@ -0,0 +1,69 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// Contains the result of validating a issuer.
+ /// The contains a collection of for each step in the token validation.
+ ///
+ internal class IssuerValidationResult : ValidationResult
+ {
+ private Exception _exception;
+
+ ///
+ /// Creates an instance of
+ ///
+ /// is the issuer that was validated successfully.
+ public IssuerValidationResult(string issuer)
+ : base(ValidationFailureType.ValidationSucceeded)
+ {
+ Issuer = issuer;
+ IsValid = true;
+ }
+
+ ///
+ /// Creates an instance of
+ ///
+ /// is the issuer that was intended to be validated.
+ /// is the that occurred during validation.
+ /// is the that occurred during validation.
+ public IssuerValidationResult(string issuer, ValidationFailureType validationFailure, ExceptionDetail exceptionDetail)
+ : base(validationFailure, exceptionDetail)
+ {
+ Issuer = issuer;
+ IsValid = false;
+ }
+
+ ///
+ /// Gets the that occurred during validation.
+ ///
+ public override Exception Exception
+ {
+ get
+ {
+ if (_exception != null || ExceptionDetail == null)
+ return _exception;
+
+ HasValidOrExceptionWasRead = true;
+ _exception = ExceptionDetail.GetException();
+ SecurityTokenInvalidIssuerException securityTokenInvalidIssuerException = _exception as SecurityTokenInvalidIssuerException;
+ if (securityTokenInvalidIssuerException != null)
+ {
+ securityTokenInvalidIssuerException.InvalidIssuer = Issuer;
+ securityTokenInvalidIssuerException.ExceptionDetail = ExceptionDetail;
+ securityTokenInvalidIssuerException.Source = "Microsoft.IdentityModel.Tokens";
+ }
+
+ return _exception;
+ }
+ }
+
+ ///
+ /// Gets the issuer that was validated or intended to be validated.
+ ///
+ public string Issuer { get; }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/LogDetail.cs b/src/Microsoft.IdentityModel.Tokens/Validation/LogDetail.cs
new file mode 100644
index 0000000000..6b91a67c1e
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/LogDetail.cs
@@ -0,0 +1,34 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using Microsoft.IdentityModel.Abstractions;
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// Contains information so that logs can be written when needed.
+ ///
+ internal class LogDetail
+ {
+ ///
+ /// Creates an instance of
+ ///
+ /// contains information about the exception that is used to generate the exception message.
+ /// is the level of the event log.
+ public LogDetail(MessageDetail messageDetail, EventLogLevel eventLogLevel)
+ {
+ EventLogLevel = eventLogLevel;
+ MessageDetail = messageDetail;
+ }
+
+ ///
+ /// Gets the level of the event log.
+ ///
+ public EventLogLevel EventLogLevel { get; }
+
+ ///
+ /// Gets the message detail.
+ ///
+ public MessageDetail MessageDetail { get; }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/MessageDetail.cs b/src/Microsoft.IdentityModel.Tokens/Validation/MessageDetail.cs
new file mode 100644
index 0000000000..800126a725
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/MessageDetail.cs
@@ -0,0 +1,46 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using Microsoft.IdentityModel.Logging;
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// Contains information about a message that is used to generate a message for logging or exceptions.
+ ///
+ internal class MessageDetail
+ {
+ private string _message;
+
+ // TODO - remove the need to create NonPII objects, we could use tuples where bool == true => object is PII.
+ // TODO - does this need to be ReadOnlyMemory?
+ ///
+ /// Creates an instance of
+ ///
+ /// The message to be formated.
+ /// The parameters for formatting.
+ public MessageDetail(string formatString, params object[] parameters)
+ {
+ // TODO - paramter validation.
+ FormatString = formatString;
+ Parameters = parameters;
+ }
+
+ ///
+ /// Gets the formatted message.
+ ///
+ public string Message
+ {
+ get
+ {
+ _message ??= LogHelper.FormatInvariant(FormatString, Parameters);
+ return _message;
+ }
+ }
+
+ private string FormatString { get; }
+
+ private object[] Parameters { get; }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/TokenValidationParameters.IssuerValidationDelegate.cs b/src/Microsoft.IdentityModel.Tokens/Validation/TokenValidationParameters.IssuerValidationDelegate.cs
new file mode 100644
index 0000000000..cab11a6bbc
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/TokenValidationParameters.IssuerValidationDelegate.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// partial class for the IssuerValidation delegate.
+ ///
+ public partial class TokenValidationParameters
+ {
+ ///
+ /// Gets or sets a delegate that will be used to validate the issuer of a .
+ ///
+ internal IssuerValidationDelegateAsync IssuerValidationDelegateAsync { get; set; }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/TokenValidationResult.cs b/src/Microsoft.IdentityModel.Tokens/Validation/TokenValidationResult.cs
similarity index 85%
rename from src/Microsoft.IdentityModel.Tokens/TokenValidationResult.cs
rename to src/Microsoft.IdentityModel.Tokens/Validation/TokenValidationResult.cs
index 6714c71b9e..46c90738e0 100644
--- a/src/Microsoft.IdentityModel.Tokens/TokenValidationResult.cs
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/TokenValidationResult.cs
@@ -19,10 +19,6 @@ public class TokenValidationResult
private readonly TokenValidationParameters _validationParameters;
private readonly TokenHandler _tokenHandler;
- private Exception _exception;
- private bool _hasIsValidOrExceptionBeenRead = false;
- private bool _isValid = false;
-
// Fields lazily initialized in a thread-safe manner. _claimsIdentity is protected by the _claimsIdentitySyncObj
// lock, and since null is a valid initialized value, _claimsIdentityInitialized tracks whether or not it's valid.
// _claims is constructed by reading the data from the ClaimsIdentity and is synchronized using Interlockeds
@@ -37,6 +33,11 @@ public class TokenValidationResult
private ClaimsIdentity _claimsIdentity;
private Dictionary _claims;
private Dictionary _propertyBag;
+ // TODO - lazy creation of _validationResults
+ private List _validationResults = [];
+
+ private Exception _exception;
+ private bool _isValid;
///
/// Creates an instance of
@@ -60,6 +61,18 @@ internal TokenValidationResult(SecurityToken securityToken, TokenHandler tokenHa
SecurityToken = securityToken;
}
+ ///
+ /// Adds a to the list of .
+ ///
+ /// the associated with one of the validation steps. For example .
+ internal void AddValidationResult(ValidationResult validationResult)
+ {
+ if (validationResult is null)
+ throw LogHelper.LogArgumentNullException(nameof(validationResult));
+
+ _validationResults.Add(validationResult);
+ }
+
///
/// The created from the validated security token.
///
@@ -67,7 +80,7 @@ public IDictionary Claims
{
get
{
- if (!_hasIsValidOrExceptionBeenRead)
+ if (!HasValidOrExceptionWasRead)
LogHelper.LogWarning(LogMessages.IDX10109);
if (_claims is null && ClaimsIdentity is { } ci)
@@ -162,7 +175,7 @@ public Exception Exception
{
get
{
- _hasIsValidOrExceptionBeenRead = true;
+ HasValidOrExceptionWasRead = true;
return _exception;
}
set
@@ -171,6 +184,8 @@ public Exception Exception
}
}
+ internal bool HasValidOrExceptionWasRead { get; set; }
+
///
/// Gets or sets the issuer that was found in the token.
///
@@ -183,7 +198,7 @@ public bool IsValid
{
get
{
- _hasIsValidOrExceptionBeenRead = true;
+ HasValidOrExceptionWasRead = true;
return _isValid;
}
set
@@ -228,5 +243,19 @@ public bool IsValid
/// (e.g for a JSON Web Token, from the "typ" header).
///
public string TokenType { get; set; }
+
+ ///
+ /// Gets the list of that contains the result of validating the token.
+ ///
+ internal IReadOnlyList ValidationResults
+ {
+ get
+ {
+ if (_validationResults is null)
+ Interlocked.CompareExchange(ref _validationResults, new List(), null);
+
+ return _validationResults;
+ }
+ }
}
}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationDelegates.cd b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationDelegates.cd
new file mode 100644
index 0000000000..a6af5bfb82
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationDelegates.cd
@@ -0,0 +1,21 @@
+
+
+
+
+
+ YAgEEAQAKMQck0AAi5R6AACRWgBkBQIAAQgYQsaIkxA=
+ Validation\TokenValidationParameters.IssuerValidationDelegate.cs
+
+
+
+
+
+
+
+
+ AAAAAAAAAACAAAAAACAQBAAAAAAAAAAAgAAAAAAAAAA=
+ Validation\Validators.Issuer.cs
+
+
+
+
\ No newline at end of file
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationFailureType.cs b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationFailureType.cs
new file mode 100644
index 0000000000..3d872bb63a
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationFailureType.cs
@@ -0,0 +1,49 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// The type of the failure that occurred when validating a .
+ ///
+ internal abstract class ValidationFailureType
+ {
+ ///
+ /// Creates an instance of
+ ///
+ protected ValidationFailureType(string name)
+ {
+ Name = name;
+ }
+
+ ///
+ /// Gets the name of the .
+ ///
+ public string Name { get; }
+
+ ///
+ /// Defines a type that represents a required parameter was null.
+ ///
+ public static readonly ValidationFailureType NullArgument = new NullArgumentFailure("NullArgument");
+ private class NullArgumentFailure : ValidationFailureType { internal NullArgumentFailure(string name) : base(name) { } }
+
+ ///
+ /// Defines a type that represents that issuer validation failed.
+ ///
+ public static readonly ValidationFailureType IssuerValidationFailed = new IssuerValidationFailure("IssuerValidationFailed");
+ private class IssuerValidationFailure : ValidationFailureType { internal IssuerValidationFailure(string name) : base(name) { } }
+
+ ///
+ /// Defines a type that represents that no evaluation has taken place.
+ ///
+ public static readonly ValidationFailureType ValidationNotEvaluated = new NotEvaluated("NotEvaluated");
+ private class NotEvaluated : ValidationFailureType { internal NotEvaluated(string name) : base(name) { } }
+
+ ///
+ /// Defines a type that represents that no evaluation has taken place.
+ ///
+ public static readonly ValidationFailureType ValidationSucceeded = new Succeeded("Succeeded");
+ private class Succeeded : ValidationFailureType { internal Succeeded(string name) : base(name) { } }
+
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationResult.cs b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationResult.cs
new file mode 100644
index 0000000000..f4d8ce0dc0
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationResult.cs
@@ -0,0 +1,110 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// Contains results of a single step in validating a .
+ /// A maintains a list of for each step in the token validation.
+ ///
+ internal abstract class ValidationResult
+ {
+ private bool _isValid = false;
+
+ ///
+ /// Creates an instance of
+ ///
+ protected ValidationResult()
+ {
+ ValidationFailureType = ValidationFailureType.ValidationNotEvaluated;
+ }
+
+ ///
+ /// Creates an instance of
+ ///
+ /// The that occurred during validation.
+ protected ValidationResult(ValidationFailureType validationFailureType)
+ {
+ ValidationFailureType = validationFailureType;
+ }
+
+ ///
+ /// Creates an instance of
+ ///
+ /// The that occurred during validation.
+ /// The representing the that occurred during validation.
+ protected ValidationResult(ValidationFailureType validationFailureType, ExceptionDetail exceptionDetail)
+ {
+ ValidationFailureType = validationFailureType;
+ ExceptionDetail = exceptionDetail;
+ }
+
+ ///
+ /// Adds a new stack frame to the exception details.
+ ///
+ ///
+ public void AddStackFrame(StackFrame stackFrame)
+ {
+ ExceptionDetail.StackFrames.Add(stackFrame);
+ }
+
+ ///
+ /// Gets the that occurred during validation.
+ ///
+ public abstract Exception Exception { get; }
+
+ ///
+ /// Gets the that occurred during validation.
+ ///
+ public ExceptionDetail ExceptionDetail { get; }
+
+ ///
+ /// True if the token was successfully validated, false otherwise.
+ ///
+ public bool IsValid
+ {
+ get
+ {
+ HasValidOrExceptionWasRead = true;
+ return _isValid;
+ }
+ set
+ {
+ _isValid = value;
+ }
+ }
+
+ // TODO - HasValidOrExceptionWasRead, IsValid, Exception are temporary and will be removed when TokenValidationResult derives from ValidationResult.
+ ///
+ /// Gets or sets a boolean recording if IsValid or Exception was called.
+ ///
+ protected bool HasValidOrExceptionWasRead { get; set; }
+
+ ///
+ /// Logs the validation result.
+ ///
+#pragma warning disable CA1822 // Mark members as static
+ public void Log()
+#pragma warning restore CA1822 // Mark members as static
+ {
+ // TODO - Do we need this, how will it work?
+ }
+
+ ///
+ /// Contains any logs that would have been written.
+ ///
+ public IList LogDetails { get; } = new List();
+
+ ///
+ /// Gets the indicating why the validation was not satisfied.
+ ///
+ public ValidationFailureType ValidationFailureType
+ {
+ get;
+ } = ValidationFailureType.ValidationNotEvaluated;
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs
new file mode 100644
index 0000000000..9c41082c53
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs
@@ -0,0 +1,154 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.IdentityModel.Abstractions;
+using Microsoft.IdentityModel.Logging;
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// Partial class for Audience Validation.
+ ///
+ public static partial class Validators
+ {
+ ///
+ /// Determines if the audiences found in a are valid.
+ ///
+ /// The audiences found in the .
+ /// The being validated.
+ /// required for validation.
+ /// If 'validationParameters' is null.
+ /// If 'audiences' is null and is true.
+ /// If is null or whitespace and is null.
+ /// If none of the 'audiences' matched either or one of .
+ /// An EXACT match is required.
+ public static void ValidateAudience(IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
+ {
+ if (validationParameters == null)
+ throw LogHelper.LogArgumentNullException(nameof(validationParameters));
+
+ if (validationParameters.AudienceValidator != null)
+ {
+ if (!validationParameters.AudienceValidator(audiences, securityToken, validationParameters))
+ throw LogHelper.LogExceptionMessage(
+ new SecurityTokenInvalidAudienceException(
+ LogHelper.FormatInvariant(
+ LogMessages.IDX10231,
+ LogHelper.MarkAsUnsafeSecurityArtifact(securityToken, t => t.ToString())))
+ {
+ InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences)
+ });
+
+ return;
+ }
+
+ if (!validationParameters.ValidateAudience)
+ {
+ LogHelper.LogWarning(LogMessages.IDX10233);
+ return;
+ }
+
+ if (audiences == null)
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException(LogMessages.IDX10207) { InvalidAudience = null });
+
+ if (string.IsNullOrWhiteSpace(validationParameters.ValidAudience) && (validationParameters.ValidAudiences == null))
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException(LogMessages.IDX10208) { InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences) });
+
+ if (!audiences.Any())
+ throw LogHelper.LogExceptionMessage(
+ new SecurityTokenInvalidAudienceException(LogHelper.FormatInvariant(LogMessages.IDX10206))
+ { InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences) });
+
+ // create enumeration of all valid audiences from validationParameters
+ IEnumerable validationParametersAudiences;
+
+ if (validationParameters.ValidAudiences == null)
+ validationParametersAudiences = new[] { validationParameters.ValidAudience };
+ else if (string.IsNullOrWhiteSpace(validationParameters.ValidAudience))
+ validationParametersAudiences = validationParameters.ValidAudiences;
+ else
+ validationParametersAudiences = validationParameters.ValidAudiences.Concat(new[] { validationParameters.ValidAudience });
+
+ if (AudienceIsValid(audiences, validationParameters, validationParametersAudiences))
+ return;
+
+ SecurityTokenInvalidAudienceException ex = new SecurityTokenInvalidAudienceException(
+ LogHelper.FormatInvariant(LogMessages.IDX10214,
+ LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(audiences)),
+ LogHelper.MarkAsNonPII(validationParameters.ValidAudience ?? "null"),
+ LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidAudiences))))
+ { InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences) };
+
+ if (!validationParameters.LogValidationExceptions)
+ throw ex;
+
+ throw LogHelper.LogExceptionMessage(ex);
+ }
+
+ private static bool AudienceIsValid(IEnumerable audiences, TokenValidationParameters validationParameters, IEnumerable validationParametersAudiences)
+ {
+ foreach (string tokenAudience in audiences)
+ {
+ if (string.IsNullOrWhiteSpace(tokenAudience))
+ continue;
+
+ foreach (string validAudience in validationParametersAudiences)
+ {
+ if (string.IsNullOrWhiteSpace(validAudience))
+ continue;
+
+ if (AudiencesMatch(validationParameters, tokenAudience, validAudience))
+ {
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX10234, LogHelper.MarkAsNonPII(tokenAudience));
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static bool AudiencesMatch(TokenValidationParameters validationParameters, string tokenAudience, string validAudience)
+ {
+ if (validAudience.Length == tokenAudience.Length)
+ {
+ if (string.Equals(validAudience, tokenAudience))
+ return true;
+ }
+ else if (validationParameters.IgnoreTrailingSlashWhenValidatingAudience && AudiencesMatchIgnoringTrailingSlash(tokenAudience, validAudience))
+ return true;
+
+ return false;
+ }
+
+ private static bool AudiencesMatchIgnoringTrailingSlash(string tokenAudience, string validAudience)
+ {
+ int length = -1;
+
+ if (validAudience.Length == tokenAudience.Length + 1 && validAudience.EndsWith("/", StringComparison.InvariantCulture))
+ length = validAudience.Length - 1;
+ else if (tokenAudience.Length == validAudience.Length + 1 && tokenAudience.EndsWith("/", StringComparison.InvariantCulture))
+ length = tokenAudience.Length - 1;
+
+ // the length of the audiences is different by more than 1 and neither ends in a "/"
+ if (length == -1)
+ return false;
+
+ if (string.CompareOrdinal(validAudience, 0, tokenAudience, 0, length) == 0)
+ {
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX10234, LogHelper.MarkAsNonPII(tokenAudience));
+
+ return true;
+ }
+
+ return false;
+ }
+
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs
new file mode 100644
index 0000000000..faca7d71e5
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs
@@ -0,0 +1,293 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.IdentityModel.Abstractions;
+using Microsoft.IdentityModel.Logging;
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// Definition for delegate that will validate the issuer value in a token.
+ ///
+ /// The issuer to validate.
+ /// The that is being validated.
+ /// required for validation.
+ ///
+ ///
+ /// A that contains the results of validating the issuer.
+ /// This delegate is not expected to throw.
+ internal delegate Task IssuerValidationDelegateAsync(
+ string issuer,
+ SecurityToken securityToken,
+ TokenValidationParameters validationParameters,
+ CallContext callContext,
+ CancellationToken cancellationToken);
+
+ ///
+ /// IssuerValidation
+ ///
+ public static partial class Validators
+ {
+ ///
+ /// Determines if an issuer found in a is valid.
+ ///
+ /// The issuer to validate
+ /// The that is being validated.
+ /// required for validation.
+ /// The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity".
+ /// If 'validationParameters' is null.
+ /// If 'issuer' is null or whitespace and is true.
+ /// If is null or whitespace and is null.
+ /// If 'issuer' failed to matched either or one of .
+ /// An EXACT match is required.
+ public static string ValidateIssuer(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
+ {
+ return ValidateIssuer(issuer, securityToken, validationParameters, null);
+ }
+
+ ///
+ /// Determines if an issuer found in a is valid.
+ ///
+ /// The issuer to validate
+ /// The that is being validated.
+ /// required for validation.
+ /// The required for issuer and signing key validation.
+ /// The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity".
+ /// If 'validationParameters' is null.
+ /// If 'issuer' is null or whitespace and is true.
+ /// If ' configuration' is null.
+ /// If is null or whitespace and is null and is null.
+ /// If 'issuer' failed to matched either or one of or .
+ /// An EXACT match is required.
+ internal static string ValidateIssuer(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
+ {
+ ValueTask vt = ValidateIssuerAsync(issuer, securityToken, validationParameters, configuration);
+ return vt.IsCompletedSuccessfully ?
+ vt.Result :
+ vt.AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
+ }
+
+ ///
+ /// Determines if an issuer found in a is valid.
+ ///
+ /// The issuer to validate
+ /// The that is being validated.
+ /// required for validation.
+ /// The required for issuer and signing key validation.
+ /// The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity".
+ /// If 'validationParameters' is null.
+ /// If 'issuer' is null or whitespace and is true.
+ /// If ' configuration' is null.
+ /// If is null or whitespace and is null and is null.
+ /// If 'issuer' failed to matched either or one of or .
+ /// An EXACT match is required.
+ internal static async ValueTask ValidateIssuerAsync(
+ string issuer,
+ SecurityToken securityToken,
+ TokenValidationParameters validationParameters,
+ BaseConfiguration configuration)
+ {
+ if (validationParameters == null)
+ throw LogHelper.LogArgumentNullException(nameof(validationParameters));
+
+ if (validationParameters.IssuerValidatorAsync != null)
+ return await validationParameters.IssuerValidatorAsync(issuer, securityToken, validationParameters).ConfigureAwait(false);
+
+ if (validationParameters.IssuerValidatorUsingConfiguration != null)
+ return validationParameters.IssuerValidatorUsingConfiguration(issuer, securityToken, validationParameters, configuration);
+
+ if (validationParameters.IssuerValidator != null)
+ return validationParameters.IssuerValidator(issuer, securityToken, validationParameters);
+
+ if (!validationParameters.ValidateIssuer)
+ {
+ LogHelper.LogWarning(LogMessages.IDX10235);
+ return issuer;
+ }
+
+ if (string.IsNullOrWhiteSpace(issuer))
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(LogMessages.IDX10211)
+ { InvalidIssuer = issuer });
+
+ // Throw if all possible places to validate against are null or empty
+ if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer)
+ && validationParameters.ValidIssuers.IsNullOrEmpty()
+ && string.IsNullOrWhiteSpace(configuration?.Issuer))
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(LogMessages.IDX10204)
+ { InvalidIssuer = issuer });
+
+ if (configuration != null)
+ {
+ if (string.Equals(configuration.Issuer, issuer))
+ {
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer));
+
+ return issuer;
+ }
+ }
+
+ if (string.Equals(validationParameters.ValidIssuer, issuer))
+ {
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer));
+
+ return issuer;
+ }
+
+ if (validationParameters.ValidIssuers != null)
+ {
+ foreach (string str in validationParameters.ValidIssuers)
+ {
+ if (string.IsNullOrEmpty(str))
+ {
+ LogHelper.LogInformation(LogMessages.IDX10262);
+ continue;
+ }
+
+ if (string.Equals(str, issuer))
+ {
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer));
+
+ return issuer;
+ }
+ }
+ }
+
+ SecurityTokenInvalidIssuerException ex = new SecurityTokenInvalidIssuerException(
+ LogHelper.FormatInvariant(LogMessages.IDX10205,
+ LogHelper.MarkAsNonPII(issuer),
+ LogHelper.MarkAsNonPII(validationParameters.ValidIssuer ?? "null"),
+ LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidIssuers)),
+ LogHelper.MarkAsNonPII(configuration?.Issuer)))
+ { InvalidIssuer = issuer };
+
+ if (!validationParameters.LogValidationExceptions)
+ throw ex;
+
+ throw LogHelper.LogExceptionMessage(ex);
+ }
+
+ ///
+ /// Determines if an issuer found in a is valid.
+ ///
+ /// The issuer to validate
+ /// The that is being validated.
+ /// required for validation.
+ ///
+ ///
+ /// The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity".
+ /// If 'validationParameters' is null.
+ /// If 'issuer' is null or whitespace and is true.
+ /// If is null or whitespace and is null.
+ /// If 'issuer' failed to matched either or one of .
+ /// An EXACT match is required.
+ internal static async Task ValidateIssuerAsync(
+ string issuer,
+ SecurityToken securityToken,
+ TokenValidationParameters validationParameters,
+ CallContext callContext,
+ CancellationToken cancellationToken)
+ {
+ if (string.IsNullOrWhiteSpace(issuer))
+ {
+ return new IssuerValidationResult(
+ issuer,
+ ValidationFailureType.NullArgument,
+ new ExceptionDetail(
+ new MessageDetail(
+ LogMessages.IDX10211,
+ null),
+ typeof(SecurityTokenInvalidIssuerException),
+ new StackFrame(true),
+ null));
+ }
+
+ if (validationParameters == null)
+ throw LogHelper.LogArgumentNullException(nameof(validationParameters));
+
+ if (securityToken == null)
+ throw LogHelper.LogArgumentNullException(nameof(securityToken));
+
+ BaseConfiguration configuration = null;
+ if (validationParameters.ConfigurationManager != null)
+ configuration = await validationParameters.ConfigurationManager.GetBaseConfigurationAsync(cancellationToken).ConfigureAwait(false);
+
+ // Throw if all possible places to validate against are null or empty
+ if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer)
+ && validationParameters.ValidIssuers.IsNullOrEmpty()
+ && string.IsNullOrWhiteSpace(configuration?.Issuer))
+ {
+ return new IssuerValidationResult(
+ issuer,
+ ValidationFailureType.IssuerValidationFailed,
+ new ExceptionDetail(
+ new MessageDetail(
+ LogMessages.IDX10211,
+ null),
+ typeof(SecurityTokenInvalidIssuerException),
+ 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))
+ {
+ // TODO - how and when to log
+ // Logs will have to be passed back to Wilson
+ // so that they can be written to the correct place and in the correct format respecting PII.
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer), callContext);
+
+ return new IssuerValidationResult(issuer);
+ }
+ }
+
+ if (string.Equals(validationParameters.ValidIssuer, issuer))
+ {
+ return new IssuerValidationResult(issuer);
+ }
+
+ if (validationParameters.ValidIssuers != null)
+ {
+ foreach (string str in validationParameters.ValidIssuers)
+ {
+ if (string.IsNullOrEmpty(str))
+ {
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX10262);
+
+ continue;
+ }
+
+ if (string.Equals(str, issuer))
+ {
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer));
+
+ return new IssuerValidationResult(issuer);
+ }
+ }
+ }
+
+ return new IssuerValidationResult(
+ issuer,
+ ValidationFailureType.IssuerValidationFailed,
+ new ExceptionDetail(
+ new MessageDetail(
+ LogMessages.IDX10205,
+ LogHelper.MarkAsNonPII(issuer),
+ LogHelper.MarkAsNonPII(validationParameters.ValidIssuer ?? "null"),
+ LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidIssuers)),
+ LogHelper.MarkAsNonPII(configuration?.Issuer)),
+ typeof(SecurityTokenInvalidIssuerException),
+ new StackFrame(true)));
+ }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Lifetime.cs b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Lifetime.cs
new file mode 100644
index 0000000000..77c553c4db
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Lifetime.cs
@@ -0,0 +1,50 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using Microsoft.IdentityModel.Logging;
+
+namespace Microsoft.IdentityModel.Tokens
+{
+ ///
+ /// IssuerValidation
+ ///
+ public static partial class Validators
+ {
+ ///
+ /// Validates the lifetime of a .
+ ///
+ /// The 'notBefore' time found in the .
+ /// The 'expiration' time found in the .
+ /// The being validated.
+ /// required for validation.
+ /// If 'validationParameters' is null.
+ /// If 'expires.HasValue' is false and is true.
+ /// If 'notBefore' is > 'expires'.
+ /// If 'notBefore' is > DateTime.UtcNow.
+ /// If 'expires' is < DateTime.UtcNow.
+ /// All time comparisons apply .
+ public static void ValidateLifetime(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
+ {
+ if (validationParameters == null)
+ throw LogHelper.LogArgumentNullException(nameof(validationParameters));
+
+ if (validationParameters.LifetimeValidator != null)
+ {
+ if (!validationParameters.LifetimeValidator(notBefore, expires, securityToken, validationParameters))
+ throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidLifetimeException(LogHelper.FormatInvariant(LogMessages.IDX10230, securityToken))
+ { NotBefore = notBefore, Expires = expires });
+
+ return;
+ }
+
+ if (!validationParameters.ValidateLifetime)
+ {
+ LogHelper.LogInformation(LogMessages.IDX10238);
+ return;
+ }
+
+ ValidatorUtilities.ValidateLifetime(notBefore, expires, securityToken, validationParameters);
+ }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/ValidatorUtilities.cs b/src/Microsoft.IdentityModel.Tokens/ValidatorUtilities.cs
index 482f2f3d37..6c652f6a3b 100644
--- a/src/Microsoft.IdentityModel.Tokens/ValidatorUtilities.cs
+++ b/src/Microsoft.IdentityModel.Tokens/ValidatorUtilities.cs
@@ -3,6 +3,7 @@
using System;
using Microsoft.IdentityModel.Logging;
+using Microsoft.IdentityModel.Abstractions;
namespace Microsoft.IdentityModel.Tokens
{
@@ -49,7 +50,8 @@ internal static void ValidateLifetime(DateTime? notBefore, DateTime? expires, Se
});
// if it reaches here, that means lifetime of the token is valid
- LogHelper.LogInformation(LogMessages.IDX10239);
+ if (LogHelper.IsEnabled(EventLogLevel.Informational))
+ LogHelper.LogInformation(LogMessages.IDX10239);
}
}
}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validators.cs b/src/Microsoft.IdentityModel.Tokens/Validators.cs
index 2c9f9e6ca1..000ba4c617 100644
--- a/src/Microsoft.IdentityModel.Tokens/Validators.cs
+++ b/src/Microsoft.IdentityModel.Tokens/Validators.cs
@@ -2,10 +2,8 @@
// Licensed under the MIT License.
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
-using System.Threading.Tasks;
using Microsoft.IdentityModel.Abstractions;
using Microsoft.IdentityModel.Logging;
@@ -14,7 +12,7 @@ namespace Microsoft.IdentityModel.Tokens
///
/// AudienceValidator
///
- public static class Validators
+ public static partial class Validators
{
///
/// Validates if a given algorithm for a is valid.
@@ -50,283 +48,6 @@ public static void ValidateAlgorithm(string algorithm, SecurityKey securityKey,
}
}
- ///
- /// Determines if the audiences found in a are valid.
- ///
- /// The audiences found in the .
- /// The being validated.
- /// required for validation.
- /// If 'validationParameters' is null.
- /// If 'audiences' is null and is true.
- /// If is null or whitespace and is null.
- /// If none of the 'audiences' matched either or one of .
- /// An EXACT match is required.
- public static void ValidateAudience(IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
- {
- if (validationParameters == null)
- throw LogHelper.LogArgumentNullException(nameof(validationParameters));
-
- if (validationParameters.AudienceValidator != null)
- {
- if (!validationParameters.AudienceValidator(audiences, securityToken, validationParameters))
- throw LogHelper.LogExceptionMessage(
- new SecurityTokenInvalidAudienceException(
- LogHelper.FormatInvariant(
- LogMessages.IDX10231,
- LogHelper.MarkAsUnsafeSecurityArtifact(securityToken, t => t.ToString())))
- {
- InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences)
- });
-
- return;
- }
-
- if (!validationParameters.ValidateAudience)
- {
- LogHelper.LogWarning(LogMessages.IDX10233);
- return;
- }
-
- if (audiences == null)
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException(LogMessages.IDX10207) { InvalidAudience = null });
-
- if (string.IsNullOrWhiteSpace(validationParameters.ValidAudience) && (validationParameters.ValidAudiences == null))
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException(LogMessages.IDX10208) { InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences) });
-
- if (!audiences.Any())
- throw LogHelper.LogExceptionMessage(
- new SecurityTokenInvalidAudienceException(LogHelper.FormatInvariant(LogMessages.IDX10206))
- { InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences) });
-
- // create enumeration of all valid audiences from validationParameters
- IEnumerable validationParametersAudiences;
-
- if (validationParameters.ValidAudiences == null)
- validationParametersAudiences = new[] { validationParameters.ValidAudience };
- else if (string.IsNullOrWhiteSpace(validationParameters.ValidAudience))
- validationParametersAudiences = validationParameters.ValidAudiences;
- else
- validationParametersAudiences = validationParameters.ValidAudiences.Concat(new[] { validationParameters.ValidAudience });
-
- if (AudienceIsValid(audiences, validationParameters, validationParametersAudiences))
- return;
-
- SecurityTokenInvalidAudienceException ex = new SecurityTokenInvalidAudienceException(
- LogHelper.FormatInvariant(LogMessages.IDX10214,
- LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(audiences)),
- LogHelper.MarkAsNonPII(validationParameters.ValidAudience ?? "null"),
- LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidAudiences))))
- { InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences) };
-
- if (!validationParameters.LogValidationExceptions)
- throw ex;
-
- throw LogHelper.LogExceptionMessage(ex);
- }
-
- private static bool AudienceIsValid(IEnumerable audiences, TokenValidationParameters validationParameters, IEnumerable validationParametersAudiences)
- {
- foreach (string tokenAudience in audiences)
- {
- if (string.IsNullOrWhiteSpace(tokenAudience))
- continue;
-
- foreach (string validAudience in validationParametersAudiences)
- {
- if (string.IsNullOrWhiteSpace(validAudience))
- continue;
-
- if (AudiencesMatch(validationParameters, tokenAudience, validAudience))
- {
- if (LogHelper.IsEnabled(EventLogLevel.Informational))
- LogHelper.LogInformation(LogMessages.IDX10234, LogHelper.MarkAsNonPII(tokenAudience));
-
- return true;
- }
- }
- }
-
- return false;
- }
-
- private static bool AudiencesMatch(TokenValidationParameters validationParameters, string tokenAudience, string validAudience)
- {
- if (validAudience.Length == tokenAudience.Length)
- {
- if (string.Equals(validAudience, tokenAudience))
- return true;
- }
- else if (validationParameters.IgnoreTrailingSlashWhenValidatingAudience && AudiencesMatchIgnoringTrailingSlash(tokenAudience, validAudience))
- return true;
-
- return false;
- }
-
- private static bool AudiencesMatchIgnoringTrailingSlash(string tokenAudience, string validAudience)
- {
- int length = -1;
-
- if (validAudience.Length == tokenAudience.Length + 1 && validAudience.EndsWith("/", StringComparison.InvariantCulture))
- length = validAudience.Length - 1;
- else if (tokenAudience.Length == validAudience.Length + 1 && tokenAudience.EndsWith("/", StringComparison.InvariantCulture))
- length = tokenAudience.Length - 1;
-
- // the length of the audiences is different by more than 1 and neither ends in a "/"
- if (length == -1)
- return false;
-
- if (string.CompareOrdinal(validAudience, 0, tokenAudience, 0, length) == 0)
- {
- if (LogHelper.IsEnabled(EventLogLevel.Informational))
- LogHelper.LogInformation(LogMessages.IDX10234, LogHelper.MarkAsNonPII(tokenAudience));
-
- return true;
- }
-
- return false;
- }
-
- ///
- /// Determines if an issuer found in a is valid.
- ///
- /// The issuer to validate
- /// The that is being validated.
- /// required for validation.
- /// The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity".
- /// If 'validationParameters' is null.
- /// If 'issuer' is null or whitespace and is true.
- /// If is null or whitespace and is null.
- /// If 'issuer' failed to matched either or one of .
- /// An EXACT match is required.
- public static string ValidateIssuer(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
- {
- return ValidateIssuer(issuer, securityToken, validationParameters, null);
- }
-
- ///
- /// Determines if an issuer found in a is valid.
- ///
- /// The issuer to validate
- /// The that is being validated.
- /// required for validation.
- /// The required for issuer and signing key validation.
- /// The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity".
- /// If 'validationParameters' is null.
- /// If 'issuer' is null or whitespace and is true.
- /// If ' configuration' is null.
- /// If is null or whitespace and is null and is null.
- /// If 'issuer' failed to matched either or one of or .
- /// An EXACT match is required.
- internal static string ValidateIssuer(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
- {
- ValueTask vt = ValidateIssuerAsync(issuer, securityToken, validationParameters, configuration);
- return vt.IsCompletedSuccessfully ?
- vt.Result :
- vt.AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
- }
-
- ///
- /// Determines if an issuer found in a is valid.
- ///
- /// The issuer to validate
- /// The that is being validated.
- /// required for validation.
- /// The required for issuer and signing key validation.
- /// The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity".
- /// If 'validationParameters' is null.
- /// If 'issuer' is null or whitespace and is true.
- /// If ' configuration' is null.
- /// If is null or whitespace and is null and is null.
- /// If 'issuer' failed to matched either or one of or .
- /// An EXACT match is required.
- internal static async ValueTask ValidateIssuerAsync(
- string issuer,
- SecurityToken securityToken,
- TokenValidationParameters validationParameters,
- BaseConfiguration configuration)
- {
- if (validationParameters == null)
- throw LogHelper.LogArgumentNullException(nameof(validationParameters));
-
- if (validationParameters.IssuerValidatorAsync != null)
- return await validationParameters.IssuerValidatorAsync(issuer, securityToken, validationParameters).ConfigureAwait(false);
-
- if (validationParameters.IssuerValidatorUsingConfiguration != null)
- return validationParameters.IssuerValidatorUsingConfiguration(issuer, securityToken, validationParameters, configuration);
-
- if (validationParameters.IssuerValidator != null)
- return validationParameters.IssuerValidator(issuer, securityToken, validationParameters);
-
- if (!validationParameters.ValidateIssuer)
- {
- LogHelper.LogWarning(LogMessages.IDX10235);
- return issuer;
- }
-
- if (string.IsNullOrWhiteSpace(issuer))
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(LogMessages.IDX10211)
- { InvalidIssuer = issuer });
-
- // Throw if all possible places to validate against are null or empty
- if ( string.IsNullOrWhiteSpace(validationParameters.ValidIssuer)
- && validationParameters.ValidIssuers.IsNullOrEmpty()
- && string.IsNullOrWhiteSpace(configuration?.Issuer))
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(LogMessages.IDX10204)
- { InvalidIssuer = issuer });
-
- if (configuration != null)
- {
- if (string.Equals(configuration.Issuer, issuer))
- {
- if (LogHelper.IsEnabled(EventLogLevel.Informational))
- LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer));
-
- return issuer;
- }
- }
-
- if (string.Equals(validationParameters.ValidIssuer, issuer))
- {
- if (LogHelper.IsEnabled(EventLogLevel.Informational))
- LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer));
-
- return issuer;
- }
-
- if (validationParameters.ValidIssuers != null)
- {
- foreach (string str in validationParameters.ValidIssuers)
- {
- if (string.IsNullOrEmpty(str))
- {
- LogHelper.LogInformation(LogMessages.IDX10262);
- continue;
- }
-
- if (string.Equals(str, issuer))
- {
- if (LogHelper.IsEnabled(EventLogLevel.Informational))
- LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer));
-
- return issuer;
- }
- }
- }
-
- SecurityTokenInvalidIssuerException ex = new SecurityTokenInvalidIssuerException(
- LogHelper.FormatInvariant(LogMessages.IDX10205,
- LogHelper.MarkAsNonPII(issuer),
- LogHelper.MarkAsNonPII(validationParameters.ValidIssuer ?? "null"),
- LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidIssuers)),
- LogHelper.MarkAsNonPII(configuration?.Issuer)))
- { InvalidIssuer = issuer };
-
- if (!validationParameters.LogValidationExceptions)
- throw ex;
-
- throw LogHelper.LogExceptionMessage(ex);
- }
-
///
/// Validates the that signed a .
///
@@ -422,42 +143,6 @@ internal static void ValidateIssuerSigningKeyLifeTime(SecurityKey securityKey, T
}
}
- ///
- /// Validates the lifetime of a .
- ///
- /// The 'notBefore' time found in the .
- /// The 'expiration' time found in the .
- /// The being validated.
- /// required for validation.
- /// If 'validationParameters' is null.
- /// If 'expires.HasValue' is false and is true.
- /// If 'notBefore' is > 'expires'.
- /// If 'notBefore' is > DateTime.UtcNow.
- /// If 'expires' is < DateTime.UtcNow.
- /// All time comparisons apply .
- public static void ValidateLifetime(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
- {
- if (validationParameters == null)
- throw LogHelper.LogArgumentNullException(nameof(validationParameters));
-
- if (validationParameters.LifetimeValidator != null)
- {
- if (!validationParameters.LifetimeValidator(notBefore, expires, securityToken, validationParameters))
- throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidLifetimeException(LogHelper.FormatInvariant(LogMessages.IDX10230, securityToken))
- { NotBefore = notBefore, Expires = expires });
-
- return;
- }
-
- if (!validationParameters.ValidateLifetime)
- {
- LogHelper.LogInformation(LogMessages.IDX10238);
- return;
- }
-
- ValidatorUtilities.ValidateLifetime(notBefore, expires, securityToken, validationParameters);
- }
-
///
/// Validates if a token has been replayed.
///
diff --git a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerTests.cs b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerTests.cs
index 02f308f804..bd041cac2f 100644
--- a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerTests.cs
+++ b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerTests.cs
@@ -2744,30 +2744,6 @@ public static TheoryData RoundTripJWEKeyWrapTestCases
EncryptingCredentials = new EncryptingCredentials(KeyingMaterial.RsaSecurityKey_2048, SecurityAlgorithms.RsaOAEP, SecurityAlgorithms.Aes128CbcHmacSha256)
},
new CreateTokenTheoryData
- {
- TestId = "RsaOAEP256_Aes128CbcHmacSha256",
- ValidationParameters = Default.TokenValidationParameters(KeyingMaterial.RsaSecurityKey_2048, Default.SymmetricSigningKey256),
- Payload = Default.PayloadString,
- SigningCredentials = Default.SymmetricSigningCredentials,
- EncryptingCredentials = new EncryptingCredentials(KeyingMaterial.RsaSecurityKey_2048, SecurityAlgorithms.RsaOAEP256, SecurityAlgorithms.Aes128CbcHmacSha256)
- },
- new CreateTokenTheoryData
- {
- TestId = "RsaOAEP256_Aes192CbcHmacSha384",
- ValidationParameters = Default.TokenValidationParameters(KeyingMaterial.RsaSecurityKey_2048, Default.SymmetricSigningKey256),
- Payload = Default.PayloadString,
- SigningCredentials = Default.SymmetricSigningCredentials,
- EncryptingCredentials = new EncryptingCredentials(KeyingMaterial.RsaSecurityKey_2048, SecurityAlgorithms.RsaOAEP256, SecurityAlgorithms.Aes192CbcHmacSha384)
- },
- new CreateTokenTheoryData
- {
- TestId = "RsaOAEP256_Aes256CbcHmacSha512",
- ValidationParameters = Default.TokenValidationParameters(KeyingMaterial.RsaSecurityKey_2048, Default.SymmetricSigningKey256),
- Payload = Default.PayloadString,
- SigningCredentials = Default.SymmetricSigningCredentials,
- EncryptingCredentials = new EncryptingCredentials(KeyingMaterial.RsaSecurityKey_2048, SecurityAlgorithms.RsaOAEP256, SecurityAlgorithms.Aes256CbcHmacSha512)
- },
- new CreateTokenTheoryData
{
TestId = "RsaOAEP_Aes192CbcHmacSha384",
ValidationParameters = Default.TokenValidationParameters(KeyingMaterial.RsaSecurityKey_2048, Default.SymmetricSigningKey256),
@@ -3547,7 +3523,7 @@ public static TheoryData ValidateJwsWithConfigTheoryData
incorrectSigningKeysConfig.SigningKeys.Add(KeyingMaterial.X509SecurityKey2);
theoryData.Add(new JwtTheoryData
{
- TestId = nameof(Default.AsymmetricJws) + "_" + "TVPInvalid" + "_" + "ConfigSigningKeysInvalid" + "_SignatureValidatorReturnsValidToken",
+ TestId = nameof(Default.AsymmetricJws) + "_TVPInvalid_ConfigSigningKeysInvalid_SignatureValidatorReturnsValidToken",
Token = Default.AsymmetricJws,
ValidationParameters = new TokenValidationParameters
{
diff --git a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/Microsoft.IdentityModel.JsonWebTokens.Tests.csproj b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/Microsoft.IdentityModel.JsonWebTokens.Tests.csproj
index e333ac1f95..523c78d729 100644
--- a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/Microsoft.IdentityModel.JsonWebTokens.Tests.csproj
+++ b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/Microsoft.IdentityModel.JsonWebTokens.Tests.csproj
@@ -20,6 +20,10 @@
+
+
+
+
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultCryptoProviderTests.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultCryptoProviderTests.cs
deleted file mode 100644
index 39e83e852c..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultCryptoProviderTests.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System.Threading.Tasks;
-using Microsoft.Azure.KeyVault.WebKey;
-using Microsoft.IdentityModel.TestUtils;
-using Microsoft.IdentityModel.Tokens;
-using Xunit;
-using static Microsoft.IdentityModel.KeyVaultExtensions.KeyVaultSecurityKey;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public class KeyVaultCryptoProviderTests
- {
- [Fact]
- public void ShouldCacheSignatureProvider()
- {
- TestUtilities.WriteHeader($"{this}.ShouldCacheSignatureProvider");
- var context = new CompareContext($"{this}.ShouldCacheSignatureProvider");
- var keyVaultKeyWithEmptyKid = new CustomKeyVaultSecurityKey("test", new AuthenticationCallback((string authority, string resource, string scope) => Task.FromResult(string.Empty)));
- var keyVaultCryptoProvider = new KeyVaultCryptoProvider();
- var signatureProvider = keyVaultCryptoProvider.Create(JsonWebKeySignatureAlgorithm.RS256, keyVaultKeyWithEmptyKid, true);
- if (keyVaultCryptoProvider.CryptoProviderCache.TryGetSignatureProvider(keyVaultKeyWithEmptyKid, SecurityAlgorithms.RsaSha256Signature, typeof(KeyVaultSignatureProvider).ToString(), true, out var _))
- context.Diffs.Add("A SignatureProvider was added to keyVaultCryptoProvider.CryptoProviderCache.CryptoProviderCache, but ShouldCacheSignatureProvider() should return false as the key has an empty key id.");
-
- CryptoProviderFactory.Default.ReleaseSignatureProvider(signatureProvider as KeyVaultSignatureProvider);
-
- TestUtilities.AssertFailIfErrors(context);
- }
-
- public class CustomKeyVaultSecurityKey : KeyVaultSecurityKey
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public CustomKeyVaultSecurityKey(string keyIdentifier, AuthenticationCallback callback) : base(keyIdentifier, callback)
- {
- }
-
- internal override string InternalId => "";
- }
- }
-}
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultKeyWrapProviderTests.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultKeyWrapProviderTests.cs
deleted file mode 100644
index e87b5fcca2..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultKeyWrapProviderTests.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using Microsoft.Azure.KeyVault;
-using Microsoft.IdentityModel.TestUtils;
-using Microsoft.IdentityModel.Tokens;
-using Xunit;
-
-#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public class KeyVaultKeyWrapProviderTests
- {
- private readonly MockKeyVaultClient _client;
- private readonly SecurityKey _key;
-
- public KeyVaultKeyWrapProviderTests()
- {
- _client = new MockKeyVaultClient();
- _key = new KeyVaultSecurityKey(KeyVaultUtilities.CreateKeyIdentifier(), keySize: default);
- }
-
- [Theory, MemberData(nameof(DisposeProviderTheoryData))]
- public void DisposeProviderTest(KeyWrapProviderTheoryData theoryData)
- {
- var context = TestUtilities.WriteHeader($"{this}.DisposeProviderTest", theoryData);
-
- try
- {
- var provider = new KeyVaultKeyWrapProvider(_key, theoryData.Algorithm, _client);
- _key.CryptoProviderFactory.ReleaseKeyWrapProvider(provider);
-
- theoryData.ExpectedException.ProcessNoException(context);
- }
- catch (Exception exception)
- {
- theoryData.ExpectedException.ProcessException(exception, context);
- }
-
- TestUtilities.AssertFailIfErrors(context);
- }
-
- public static TheoryData DisposeProviderTheoryData
- {
- get => new TheoryData
- {
- new KeyWrapProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaPKCS1,
- ExpectedException = ExpectedException.NoExceptionExpected,
- First = true,
- TestId = nameof(SecurityAlgorithms.RsaPKCS1),
- },
- new KeyWrapProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaOAEP,
- ExpectedException = ExpectedException.NoExceptionExpected,
- TestId = nameof(SecurityAlgorithms.RsaOAEP),
- },
- new KeyWrapProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaOAEP256,
- ExpectedException = ExpectedException.NoExceptionExpected,
- TestId = nameof(SecurityAlgorithms.RsaOAEP256),
- },
- };
- }
-
- [Theory, MemberData(nameof(KeyWrapProviderTheoryData))]
- public void WrapUnwrapKeyTest(KeyWrapProviderTheoryData theoryData)
- {
- var context = TestUtilities.WriteHeader($"{this}.WrapUnwrapKeyTest", theoryData);
-
- try
- {
- var provider = new KeyVaultKeyWrapProvider(_key, theoryData.Algorithm, _client);
- if (provider == null)
- context.AddDiff("(provider == null)");
-
- var keyBytes = Guid.NewGuid().ToByteArray();
- var wrappedKey = provider.WrapKey(keyBytes);
- if (wrappedKey == null)
- context.AddDiff("(wrappedKey == null)");
-
- if (_client.ExpectedKeyWrapLength != wrappedKey.Length)
- context.AddDiff($"_client.ExpectedKeyWrapLength != wrappedKey.Length. {_client.ExpectedKeyWrapLength} != {wrappedKey.Length}");
-
- if (Utility.AreEqual(keyBytes, wrappedKey))
- context.AddDiff("Utility.AreEqual(keyBytes, wrappedKey)");
-
- var unwrappedKey = provider.UnwrapKey(wrappedKey);
- if (unwrappedKey == null)
- context.AddDiff("(unwrappedKey == null)");
-
- IdentityComparer.AreBytesEqual(keyBytes, unwrappedKey, context);
-
- theoryData.ExpectedException.ProcessNoException(context);
- }
- catch (Exception exception)
- {
- theoryData.ExpectedException.ProcessException(exception, context);
- }
-
- TestUtilities.AssertFailIfErrors(context);
- }
-
- public static TheoryData KeyWrapProviderTheoryData
- {
- get => new TheoryData
- {
- new KeyWrapProviderTheoryData
- {
- Algorithm = null,
- ExpectedException = ExpectedException.ArgumentNullException(),
- First = true,
- TestId = "NullAlgorithm",
- },
- new KeyWrapProviderTheoryData
- {
- Algorithm = string.Empty,
- ExpectedException = ExpectedException.ArgumentNullException(),
- TestId = "EmptyAlgorithm",
- },
- new KeyWrapProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaPKCS1,
- TestId = nameof(SecurityAlgorithms.RsaPKCS1),
- },
- new KeyWrapProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaOAEP,
- TestId = nameof(SecurityAlgorithms.RsaOAEP),
- },
- };
- }
- }
-}
-
-#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyAuthenticationCallbackTheoryData.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyAuthenticationCallbackTheoryData.cs
deleted file mode 100644
index 39747206c6..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyAuthenticationCallbackTheoryData.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System.Threading.Tasks;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public class KeyVaultSecurityKeyAuthenticationCallbackTheoryData : KeyVaultSecurityKeyTheoryData
- {
- public KeyVaultSecurityKey.AuthenticationCallback Callback { get; set; } = new KeyVaultSecurityKey.AuthenticationCallback((string authority, string resource, string scope) => Task.FromResult(string.Empty));
- }
-}
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyConfidentialClientTheoryData.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyConfidentialClientTheoryData.cs
deleted file mode 100644
index 75e3f1bca9..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyConfidentialClientTheoryData.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public class KeyVaultSecurityKeyConfidentialClientTheoryData : KeyVaultSecurityKeyTheoryData
- {
- public string ClientId { get; set; } = $"{Guid.NewGuid():D}";
- public string ClientSecret { get; set; } = Guid.NewGuid().ToString();
- }
-}
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyManagedServiceIdentityTheoryData.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyManagedServiceIdentityTheoryData.cs
deleted file mode 100644
index f5c096fa16..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyManagedServiceIdentityTheoryData.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public class KeyVaultSecurityKeyManagedServiceIdentityTheoryData : KeyVaultSecurityKeyTheoryData
- {
- }
-}
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyTests.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyTests.cs
deleted file mode 100644
index 9badfe1f52..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyTests.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using System.Reflection;
-using Microsoft.Azure.KeyVault.Models;
-using Microsoft.IdentityModel.TestUtils;
-using Xunit;
-
-#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public class KeyVaultSecurityKeyTests
- {
- private static ExpectedException ArgumentNullExceptionExpected = new ExpectedException(typeExpected: typeof(TargetInvocationException), substringExpected: "Exception has been thrown by the target of an invocation.", innerTypeExpected: typeof(ArgumentNullException));
- private static ExpectedException KeyVaultErrorExceptionExpected = new ExpectedException(typeExpected: typeof(TargetInvocationException), substringExpected: "Exception has been thrown by the target of an invocation.", innerTypeExpected: typeof(KeyVaultErrorException));
-
- [Theory, MemberData(nameof(KeyVaultSecurityKeyAuthenticationCallbackTheoryData))]
- public void AuthenticationCallbackConstructorParams(KeyVaultSecurityKeyAuthenticationCallbackTheoryData theoryData)
- {
- var context = TestUtilities.WriteHeader($"{this}.AuthenticationCallbackConstructorParams", theoryData);
-
- try
- {
- _ = Activator.CreateInstance(theoryData.Type, new object[] { theoryData.KeyIdentifier, theoryData.Callback });
- }
- catch (Exception ex)
- {
- theoryData.ExpectedException.ProcessException(ex, context);
- }
- }
-
- public static TheoryData KeyVaultSecurityKeyAuthenticationCallbackTheoryData
- {
- get => new TheoryData
- {
- new KeyVaultSecurityKeyAuthenticationCallbackTheoryData
- {
- // Callback = default,
- ExpectedException = ExpectedException.ArgumentNullException(),
- First = true,
- KeyIdentifier = null,
- TestId = typeof(KeyVaultSecurityKey).FullName,
- Type = typeof(KeyVaultSecurityKey),
- },
- new KeyVaultSecurityKeyAuthenticationCallbackTheoryData
- {
- // Callback = default,
- ExpectedException = ExpectedException.ArgumentNullException(),
- KeyIdentifier = string.Empty,
- TestId = typeof(KeyVaultSecurityKey).FullName,
- Type = typeof(KeyVaultSecurityKey),
- },
- new KeyVaultSecurityKeyAuthenticationCallbackTheoryData
- {
- Callback = null,
- ExpectedException = ExpectedException.ArgumentNullException(),
- // KeyIdentifier = default,
- TestId = typeof(KeyVaultSecurityKey).FullName,
- Type = typeof(KeyVaultSecurityKey),
- },
- new KeyVaultSecurityKeyAuthenticationCallbackTheoryData
- {
- // Callback = default,
- ExpectedException = KeyVaultErrorExceptionExpected,
- // KeyIdentifier = default,
- TestId = typeof(KeyVaultSecurityKey).FullName,
- Type = typeof(KeyVaultSecurityKey),
- },
- };
- }
- }
-}
-
-#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyTheoryData.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyTheoryData.cs
deleted file mode 100644
index 73dd0a20c8..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSecurityKeyTheoryData.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using Microsoft.IdentityModel.TestUtils;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public abstract class KeyVaultSecurityKeyTheoryData : TheoryDataBase
- {
- public string KeyIdentifier { get; set; } = KeyVaultUtilities.CreateKeyIdentifier();
- public Type Type { get; set; }
- }
-}
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSignatureProviderTests.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSignatureProviderTests.cs
deleted file mode 100644
index 7ab512625c..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultSignatureProviderTests.cs
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using System.Linq;
-using Microsoft.Azure.KeyVault;
-using Microsoft.IdentityModel.TestUtils;
-using Microsoft.IdentityModel.Tokens;
-using Microsoft.IdentityModel.KeyVaultExtensions;
-using Xunit;
-
-#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public class KeyVaultSignatureProviderTests
- {
- private readonly MockKeyVaultClient _client;
- private readonly SecurityKey _key;
-
- public KeyVaultSignatureProviderTests()
- {
- _client = new MockKeyVaultClient();
- _key = new KeyVaultSecurityKey(KeyVaultUtilities.CreateKeyIdentifier(), keySize: default);
- }
-
- [Theory, MemberData(nameof(DisposeProviderTheoryData))]
- public void DisposeProviderTest(SignatureProviderTheoryData theoryData)
- {
- var context = TestUtilities.WriteHeader($"{this}.DisposeProviderTest", theoryData);
-
- try
- {
- var provider = new KeyVaultSignatureProvider(_key, theoryData.Algorithm, willCreateSignatures: true, _client);
- _key.CryptoProviderFactory.ReleaseSignatureProvider(provider);
-
- theoryData.ExpectedException.ProcessNoException(context);
- }
- catch (Exception exception)
- {
- theoryData.ExpectedException.ProcessException(exception, context);
- }
-
- TestUtilities.AssertFailIfErrors(context);
- }
-
- public static TheoryData DisposeProviderTheoryData
- {
- get => new TheoryData
- {
- new SignatureProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaSha256,
- ExpectedException = ExpectedException.NoExceptionExpected,
- First = true,
- TestId = nameof(SecurityAlgorithms.RsaSha256),
- },
- new SignatureProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaSha384,
- ExpectedException = ExpectedException.NoExceptionExpected,
- TestId = nameof(SecurityAlgorithms.RsaSha384),
- },
- new SignatureProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaSha512,
- ExpectedException = ExpectedException.NoExceptionExpected,
- TestId = nameof(SecurityAlgorithms.RsaSha512),
- },
- };
- }
-
- [Theory, MemberData(nameof(SignatureProviderTheoryData))]
- public void SignatureTest(SignatureProviderTheoryData theoryData)
- {
- var context = TestUtilities.WriteHeader($"{this}.SignatureTest", theoryData);
-
- try
- {
- var provider = new KeyVaultSignatureProvider(_key, theoryData.Algorithm, willCreateSignatures: true, _client);
- if (provider == null)
- context.AddDiff("(provider == null)");
-
- var input = Guid.NewGuid().ToByteArray();
- var signature = provider.Sign(input);
-
- if (signature == null)
- context.AddDiff("(signature == null)");
-
- if (_client.ExpectedSignatureLength != signature.Length)
- context.AddDiff($"_client.ExpectedSignatureLength != signature.Length. == {_client.ExpectedSignatureLength}, {signature.Length}.");
-
- if (!provider.Verify(input, signature))
- context.AddDiff("!provider.Verify(input, signature)");
-
- var tamperedInput = new byte[input.Length];
- input.CopyTo(tamperedInput, 0);
- if (tamperedInput[0] == byte.MaxValue)
- tamperedInput[0]--;
- else
- tamperedInput[0]++;
-
- if (provider.Verify(tamperedInput, signature))
- context.AddDiff("provider.Verify(tamperedInput, signature)");
-
- foreach (var data in SignatureProviderTheoryData)
- {
- var newAlgorithm = (data.Single() as SignatureProviderTheoryData)?.Algorithm;
- if (string.IsNullOrEmpty(newAlgorithm))
- continue; // Skip invalid input
-
- // Check that a given Security Key will only validate a signature using the same hash algorithm.
- var isValidSignature = new KeyVaultSignatureProvider(_key, newAlgorithm, willCreateSignatures: false, _client).Verify(input, signature);
- if (StringComparer.Ordinal.Equals(theoryData.Algorithm, newAlgorithm))
- {
- if (!isValidSignature)
- context.AddDiff("Signature should have been valid, isValidSignature == false");
- }
- else if (isValidSignature)
- context.AddDiff("Signature should NOT have been valid, isValidSignature == true");
- }
-
- theoryData.ExpectedException.ProcessNoException(context);
- }
- catch (Exception exception)
- {
- theoryData.ExpectedException.ProcessException(exception, context);
- }
-
- TestUtilities.AssertFailIfErrors(context);
- }
-
- public static TheoryData SignatureProviderTheoryData
- {
- get => new TheoryData
- {
- new SignatureProviderTheoryData
- {
- Algorithm = null,
- ExpectedException = ExpectedException.ArgumentNullException(),
- First = true,
- TestId = "NullAlgorithm",
- },
- new SignatureProviderTheoryData
- {
- Algorithm = string.Empty,
- ExpectedException = ExpectedException.ArgumentNullException(),
- TestId = "EmptyAlgorithm",
- },
- new SignatureProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaSha256,
- TestId = nameof(SecurityAlgorithms.RsaSha256),
- },
- new SignatureProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaSha384,
- TestId = nameof(SecurityAlgorithms.RsaSha384),
- },
- new SignatureProviderTheoryData
- {
- Algorithm = SecurityAlgorithms.RsaSha512,
- TestId = nameof(SecurityAlgorithms.RsaSha512),
- },
- };
- }
- }
-}
-
-#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultUtilities.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultUtilities.cs
deleted file mode 100644
index 072a868068..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyVaultUtilities.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public static class KeyVaultUtilities
- {
- public static string CreateKeyIdentifier() => CreateKeyIdentifier("contoso.vault.azure.net", nameof(KeyVaultUtilities), $"{Guid.NewGuid():N}");
-
- public static string CreateKeyIdentifier(string vaultBaseUrl, string vaultKeyName, string vaultKeyVersion)
- {
- return new UriBuilder(Uri.UriSchemeHttps, vaultBaseUrl, -1, $"/keys/{vaultKeyName}/{vaultKeyVersion}").Uri.ToString();
- }
- }
-}
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyWrapProviderTheoryData.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyWrapProviderTheoryData.cs
deleted file mode 100644
index 5e8ab0f194..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/KeyWrapProviderTheoryData.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using Microsoft.IdentityModel.TestUtils;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- public class KeyWrapProviderTheoryData : TheoryDataBase
- {
- public string Algorithm { get; set; }
- }
-}
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/Microsoft.IdentityModel.KeyVaultExtensions.Tests.csproj b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/Microsoft.IdentityModel.KeyVaultExtensions.Tests.csproj
deleted file mode 100644
index 3c797af7a1..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/Microsoft.IdentityModel.KeyVaultExtensions.Tests.csproj
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
- Microsoft.IdentityModel.KeyVaultExtensions.Tests
- $(MSBuildThisFileDirectory)..\..\build\35MSSharedLib1024.snk
- true
- Tests for Microsoft.IdentityModel.KeyVaultExtensions
- true
- Microsoft.IdentityModel.KeyVaultExtensions.Tests
- true
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/MockKeyVaultClient.cs b/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/MockKeyVaultClient.cs
deleted file mode 100644
index 8fcbc31691..0000000000
--- a/test/Microsoft.IdentityModel.KeyVaultExtensions.Tests/MockKeyVaultClient.cs
+++ /dev/null
@@ -1,622 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-using System;
-using System.Collections.Generic;
-using System.Security.Cryptography;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Azure.KeyVault;
-using Microsoft.Azure.KeyVault.Models;
-using Microsoft.IdentityModel.TestUtils;
-using Microsoft.IdentityModel.Tokens;
-using Microsoft.Rest;
-using Microsoft.Rest.Azure;
-using Newtonsoft.Json;
-
-namespace Microsoft.IdentityModel.KeyVaultExtensions.Tests
-{
- [CLSCompliant(false)]
- public class MockKeyVaultClient : IKeyVaultClient
- {
- private readonly Microsoft.Azure.KeyVault.WebKey.JsonWebKey _key;
- private readonly RSACryptoServiceProvider _rsa;
- private bool _disposed = false;
-
- public MockKeyVaultClient()
- {
- _rsa = new RSACryptoServiceProvider();
- _rsa.ImportParameters(KeyingMaterial.RsaParameters_2048);
- _key = new Microsoft.Azure.KeyVault.WebKey.JsonWebKey(_rsa, includePrivateParameters: false);
- }
-
- public int ExpectedKeyWrapLength => 256;
-
- public int ExpectedSignatureLength => 256;
-
- public JsonSerializerSettings SerializationSettings => throw new NotImplementedException();
-
- public JsonSerializerSettings DeserializationSettings => throw new NotImplementedException();
-
- public ServiceClientCredentials Credentials => throw new NotImplementedException();
-
- public string ApiVersion => throw new NotImplementedException();
-
- public string AcceptLanguage { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
- public int? LongRunningOperationRetryTimeout { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
- public bool? GenerateClientRequestId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
- public Task> BackupCertificateWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> BackupKeyWithHttpMessagesAsync(string vaultBaseUrl, string keyName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> BackupSecretWithHttpMessagesAsync(string vaultBaseUrl, string secretName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> BackupStorageAccountWithHttpMessagesAsync(string vaultBaseUrl, string storageAccountName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> CreateCertificateWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, CertificatePolicy certificatePolicy = null, CertificateAttributes certificateAttributes = null, IDictionary tags = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> CreateKeyWithHttpMessagesAsync(string vaultBaseUrl, string keyName, string kty, int? keySize = null, IList keyOps = null, KeyAttributes keyAttributes = null, IDictionary tags = null, string curve = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> DecryptWithHttpMessagesAsync(string vaultBaseUrl, string keyName, string keyVersion, string algorithm, byte[] value, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> DeleteCertificateContactsWithHttpMessagesAsync(string vaultBaseUrl, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> DeleteCertificateIssuerWithHttpMessagesAsync(string vaultBaseUrl, string issuerName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> DeleteCertificateOperationWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> DeleteCertificateWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> DeleteKeyWithHttpMessagesAsync(string vaultBaseUrl, string keyName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> DeleteSasDefinitionWithHttpMessagesAsync(string vaultBaseUrl, string storageAccountName, string sasDefinitionName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> DeleteSecretWithHttpMessagesAsync(string vaultBaseUrl, string secretName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> DeleteStorageAccountWithHttpMessagesAsync(string vaultBaseUrl, string storageAccountName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- ///
- /// Calls and
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (!_disposed)
- {
- _disposed = true;
- if (disposing)
- {
- _rsa.Dispose();
- }
- }
- }
-
- public Task> EncryptWithHttpMessagesAsync(string vaultBaseUrl, string keyName, string keyVersion, string algorithm, byte[] value, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetCertificateContactsWithHttpMessagesAsync(string vaultBaseUrl, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetCertificateIssuersNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetCertificateIssuersWithHttpMessagesAsync(string vaultBaseUrl, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetCertificateIssuerWithHttpMessagesAsync(string vaultBaseUrl, string issuerName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetCertificateOperationWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetCertificatePolicyWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetCertificatesNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetCertificatesWithHttpMessagesAsync(string vaultBaseUrl, int? maxresults = null, bool? includePending = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetCertificateVersionsNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetCertificateVersionsWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetCertificateWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, string certificateVersion, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedCertificatesNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedCertificatesWithHttpMessagesAsync(string vaultBaseUrl, int? maxresults = null, bool? includePending = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetDeletedCertificateWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedKeysNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedKeysWithHttpMessagesAsync(string vaultBaseUrl, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetDeletedKeyWithHttpMessagesAsync(string vaultBaseUrl, string keyName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedSasDefinitionsNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedSasDefinitionsWithHttpMessagesAsync(string vaultBaseUrl, string storageAccountName, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetDeletedSasDefinitionWithHttpMessagesAsync(string vaultBaseUrl, string storageAccountName, string sasDefinitionName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedSecretsNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedSecretsWithHttpMessagesAsync(string vaultBaseUrl, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetDeletedSecretWithHttpMessagesAsync(string vaultBaseUrl, string secretName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedStorageAccountsNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetDeletedStorageAccountsWithHttpMessagesAsync(string vaultBaseUrl, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetDeletedStorageAccountWithHttpMessagesAsync(string vaultBaseUrl, string storageAccountName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetKeysNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetKeysWithHttpMessagesAsync(string vaultBaseUrl, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetKeyVersionsNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetKeyVersionsWithHttpMessagesAsync(string vaultBaseUrl, string keyName, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetKeyWithHttpMessagesAsync(string vaultBaseUrl, string keyName, string keyVersion, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- _key.Kid = GetKeyIdentifier(vaultBaseUrl, keyName, keyVersion);
- KeyAttributes attributes = new KeyAttributes(enabled: true);
- var response = new AzureOperationResponse
- {
- Body = new KeyBundle(_key, attributes),
- };
-
- return Task.FromResult(response);
- }
-
- public Task> GetPendingCertificateSigningRequestWithHttpMessagesAsync(string vault, string certificateName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetSasDefinitionsNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetSasDefinitionsWithHttpMessagesAsync(string vaultBaseUrl, string storageAccountName, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetSasDefinitionWithHttpMessagesAsync(string vaultBaseUrl, string storageAccountName, string sasDefinitionName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetSecretsNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetSecretsWithHttpMessagesAsync(string vaultBaseUrl, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetSecretVersionsNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetSecretVersionsWithHttpMessagesAsync(string vaultBaseUrl, string secretName, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetSecretWithHttpMessagesAsync(string vaultBaseUrl, string secretName, string secretVersion, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetStorageAccountsNextWithHttpMessagesAsync(string nextPageLink, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task>> GetStorageAccountsWithHttpMessagesAsync(string vaultBaseUrl, int? maxresults = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> GetStorageAccountWithHttpMessagesAsync(string vaultBaseUrl, string storageAccountName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> ImportCertificateWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, string base64EncodedCertificate, string password = null, CertificatePolicy certificatePolicy = null, CertificateAttributes certificateAttributes = null, IDictionary tags = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> ImportKeyWithHttpMessagesAsync(string vaultBaseUrl, string keyName, Microsoft.Azure.KeyVault.WebKey.JsonWebKey key, bool? hsm = null, KeyAttributes keyAttributes = null, IDictionary tags = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task> MergeCertificateWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, IList x509Certificates, CertificateAttributes certificateAttributes = null, IDictionary tags = null, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task PurgeDeletedCertificateWithHttpMessagesAsync(string vaultBaseUrl, string certificateName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task PurgeDeletedKeyWithHttpMessagesAsync(string vaultBaseUrl, string keyName, Dictionary> customHeaders = null, CancellationToken cancellationToken = default)
- {
- throw new NotImplementedException();
- }
-
- public Task