diff --git a/.gitignore b/.gitignore index 4de460ceb3..a6d8043eb3 100644 --- a/.gitignore +++ b/.gitignore @@ -210,3 +210,5 @@ backup/* /.vs/ test/ApiChangeTest/Resource/devAssemblies test/ApiChangeTest/Resource/reports +/benchmark/Microsoft.IdentityModel.Benchmarks/BenchmarkDotNet.Artifacts/results +/benchmark/Microsoft.IdentityModel.Benchmarks/.vs diff --git a/Wilson.sln b/Wilson.sln index d4c87853cc..888f40d85c 100644 --- a/Wilson.sln +++ b/Wilson.sln @@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.7.33711.374 MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmark", "benchmark", "{2F79F3C4-F4E3-46DD-8B34-8EF403A6F7F5}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BD2706C5-6C57-484D-89C8-A0CF5F8E3D19}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8905D2E3-4499-4A86-BF3E-F098F228DD59}" @@ -101,6 +103,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.Aot EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.AotCompatibility.Tests", "test\Microsoft.IdentityModel.AotCompatibility.Tests\Microsoft.IdentityModel.AotCompatibility.Tests.csproj", "{CD0EEF56-7221-4420-8181-48EE82E91306}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.Benchmarks", "benchmark\Microsoft.IdentityModel.Benchmarks\Microsoft.IdentityModel.Benchmarks.csproj", "{F1BB31E4-8865-4425-8BD4-94F1815C16E0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -243,6 +247,10 @@ Global {CD0EEF56-7221-4420-8181-48EE82E91306}.Debug|Any CPU.Build.0 = Debug|Any CPU {CD0EEF56-7221-4420-8181-48EE82E91306}.Release|Any CPU.ActiveCfg = Release|Any CPU {CD0EEF56-7221-4420-8181-48EE82E91306}.Release|Any CPU.Build.0 = Release|Any CPU + {F1BB31E4-8865-4425-8BD4-94F1815C16E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1BB31E4-8865-4425-8BD4-94F1815C16E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1BB31E4-8865-4425-8BD4-94F1815C16E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1BB31E4-8865-4425-8BD4-94F1815C16E0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -284,6 +292,7 @@ Global {EF9A4431-6D2C-4DD1-BF6B-6F2CC619DEE1} = {8905D2E3-4499-4A86-BF3E-F098F228DD59} {8105289F-3D54-4054-9738-5985F3B6CF2C} = {8905D2E3-4499-4A86-BF3E-F098F228DD59} {CD0EEF56-7221-4420-8181-48EE82E91306} = {8905D2E3-4499-4A86-BF3E-F098F228DD59} + {F1BB31E4-8865-4425-8BD4-94F1815C16E0} = {2F79F3C4-F4E3-46DD-8B34-8EF403A6F7F5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2F681326-7ED4-45F6-BD1D-1119EA388F42} diff --git a/benchmark/Microsoft.IdentityModel.Benchmarks/CreateJWETests.cs b/benchmark/Microsoft.IdentityModel.Benchmarks/CreateJWETests.cs new file mode 100644 index 0000000000..7a26618644 --- /dev/null +++ b/benchmark/Microsoft.IdentityModel.Benchmarks/CreateJWETests.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using BenchmarkDotNet.Attributes; +using Microsoft.IdentityModel.JsonWebTokens; +using Microsoft.IdentityModel.TestUtils; +using Microsoft.IdentityModel.Tokens; + +namespace Microsoft.IdentityModel.Benchmarks +{ + [Config(typeof(AntiVirusFriendlyConfig))] + [HideColumns("Type", "Job", "WarmupCount", "LaunchCount")] + [MemoryDiagnoser] + public class CreateJWETests + { + private JsonWebTokenHandler _jsonWebTokenHandler; + private JwtSecurityTokenHandler _jwtSecurityTokenHandler; + private SecurityTokenDescriptor _tokenDescriptor; + + [GlobalSetup] + public void Setup() + { + _jsonWebTokenHandler = new JsonWebTokenHandler(); + _jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); + _tokenDescriptor = new SecurityTokenDescriptor + { + SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials, + EncryptingCredentials = KeyingMaterial.DefaultSymmetricEncryptingCreds_Aes256_Sha512_512, + Subject = new ClaimsIdentity(Default.PayloadClaims), + TokenType = "TokenType" + }; + } + + [Benchmark] + public string JsonWebTokenHandler_CreateJWE() => _jsonWebTokenHandler.CreateToken(_tokenDescriptor); + + [Benchmark] + public string JwtSecurityTokenHandler_CreateJWE() => _jwtSecurityTokenHandler.CreateEncodedJwt(_tokenDescriptor); + } +} diff --git a/benchmark/Microsoft.IdentityModel.Benchmarks/CreateSignedHttpRequestTests.cs b/benchmark/Microsoft.IdentityModel.Benchmarks/CreateSignedHttpRequestTests.cs new file mode 100644 index 0000000000..d9555d2534 --- /dev/null +++ b/benchmark/Microsoft.IdentityModel.Benchmarks/CreateSignedHttpRequestTests.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using BenchmarkDotNet.Attributes; +using Microsoft.IdentityModel.Protocols.SignedHttpRequest; +using Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests; +using Microsoft.IdentityModel.Protocols; + +namespace Microsoft.IdentityModel.Benchmarks +{ + [HideColumns("Type", "Job", "WarmupCount", "LaunchCount")] + [MemoryDiagnoser] + public class CreateSignedHttpRequestTests + { + private SignedHttpRequestHandler _signedHttpRequestHandler; + private SignedHttpRequestDescriptor _signedHttpRequestDescriptor; + + [GlobalSetup] + public void Setup() + { + _signedHttpRequestHandler = new SignedHttpRequestHandler(); + _signedHttpRequestDescriptor = new SignedHttpRequestDescriptor( + SignedHttpRequestTestUtils.DefaultEncodedAccessToken, + new HttpRequestData(), + SignedHttpRequestTestUtils.DefaultSigningCredentials, + new SignedHttpRequestCreationParameters() + { + CreateM = false, + CreateP = false, + CreateU = false + }); + } + + [Benchmark] + public string SHRHandler_CreateSignedHttpRequest() => _signedHttpRequestHandler.CreateSignedHttpRequest(_signedHttpRequestDescriptor); + + } +} diff --git a/benchmark/Microsoft.IdentityModel.Benchmarks/CreateTokenTests.cs b/benchmark/Microsoft.IdentityModel.Benchmarks/CreateTokenTests.cs index b4734c37c6..da2713f724 100644 --- a/benchmark/Microsoft.IdentityModel.Benchmarks/CreateTokenTests.cs +++ b/benchmark/Microsoft.IdentityModel.Benchmarks/CreateTokenTests.cs @@ -10,16 +10,17 @@ namespace Microsoft.IdentityModel.Benchmarks { [HideColumns("Type", "Job", "WarmupCount", "LaunchCount")] + [MemoryDiagnoser] public class CreateTokenTests { - JsonWebTokenHandler jsonWebTokenHandler; - SecurityTokenDescriptor tokenDescriptor; + private JsonWebTokenHandler _jsonWebTokenHandler; + private SecurityTokenDescriptor _tokenDescriptor; [GlobalSetup] public void Setup() { - jsonWebTokenHandler = new JsonWebTokenHandler(); - tokenDescriptor = new SecurityTokenDescriptor + _jsonWebTokenHandler = new JsonWebTokenHandler(); + _tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(Default.PayloadClaims), SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials, @@ -27,7 +28,7 @@ public void Setup() } [Benchmark] - public string JsonWebTokenHandler_CreateToken() => jsonWebTokenHandler.CreateToken(tokenDescriptor); + public string JsonWebTokenHandler_CreateToken() => _jsonWebTokenHandler.CreateToken(_tokenDescriptor); } } diff --git a/benchmark/Microsoft.IdentityModel.Benchmarks/Microsoft.IdentityModel.Benchmarks.csproj b/benchmark/Microsoft.IdentityModel.Benchmarks/Microsoft.IdentityModel.Benchmarks.csproj index e8d10d498a..84f7a48b6d 100644 --- a/benchmark/Microsoft.IdentityModel.Benchmarks/Microsoft.IdentityModel.Benchmarks.csproj +++ b/benchmark/Microsoft.IdentityModel.Benchmarks/Microsoft.IdentityModel.Benchmarks.csproj @@ -1,8 +1,14 @@ + Microsoft.IdentityModel.Benchmarks + Microsoft.IdentityModel.Benchmarks Exe net8.0 + True + True + $(MSBuildThisFileDirectory)..\..\build\35MSSharedLib1024.snk + False @@ -18,6 +24,8 @@ + + diff --git a/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateJWEAsyncTests.cs b/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateJWEAsyncTests.cs new file mode 100644 index 0000000000..9aef334bf4 --- /dev/null +++ b/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateJWEAsyncTests.cs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using BenchmarkDotNet.Attributes; +using Microsoft.IdentityModel.JsonWebTokens; +using Microsoft.IdentityModel.TestUtils; +using Microsoft.IdentityModel.Tokens; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Threading.Tasks; + +namespace Microsoft.IdentityModel.Benchmarks +{ + [Config(typeof(AntiVirusFriendlyConfig))] + [HideColumns("Type", "Job", "WarmupCount", "LaunchCount")] + [MemoryDiagnoser] + public class ValidateJWEAsyncTests + { + private JsonWebTokenHandler _jsonWebTokenHandler; + private JwtSecurityTokenHandler _jwtSecurityTokenHandler; + private SecurityTokenDescriptor _tokenDescriptor; + private string _jweFromJsonHandler; + private string _jweFromJwtHandler; + private TokenValidationParameters _validationParameters; + + [GlobalSetup] + public void Setup() + { + _jsonWebTokenHandler = new JsonWebTokenHandler(); + _jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); + _tokenDescriptor = new SecurityTokenDescriptor + { + SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials, + EncryptingCredentials = KeyingMaterial.DefaultSymmetricEncryptingCreds_Aes256_Sha512_512, + Subject = new ClaimsIdentity(Default.PayloadClaims), + TokenType = "TokenType" + }; + _jweFromJsonHandler = _jsonWebTokenHandler.CreateToken(_tokenDescriptor); + _jweFromJwtHandler = _jwtSecurityTokenHandler.CreateEncodedJwt(_tokenDescriptor); + _validationParameters = new TokenValidationParameters + { + IssuerSigningKey = KeyingMaterial.JsonWebKeyRsa256SigningCredentials.Key, + TokenDecryptionKey = KeyingMaterial.DefaultSymmetricSecurityKey_512, + ValidAudience = Default.Audience, + ValidIssuer = Default.Issuer + }; + } + + [Benchmark] + public async Task JsonWebTokenHandler_ValidateJWEAsync() => await _jsonWebTokenHandler.ValidateTokenAsync(_jweFromJsonHandler, _validationParameters); + + [Benchmark] + public ClaimsPrincipal JwtSecurityTokenHandler_ValidateJWEAsync() => _jwtSecurityTokenHandler.ValidateToken(_jweFromJwtHandler, _validationParameters, out _); + } +} diff --git a/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateSignedHttpRequestAsyncTests.cs b/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateSignedHttpRequestAsyncTests.cs new file mode 100644 index 0000000000..931cf3c316 --- /dev/null +++ b/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateSignedHttpRequestAsyncTests.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using BenchmarkDotNet.Attributes; +using Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests; +using Microsoft.IdentityModel.Protocols.SignedHttpRequest; +using Microsoft.IdentityModel.Protocols; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.IdentityModel.Benchmarks +{ + [HideColumns("Type", "Job", "WarmupCount", "LaunchCount")] + [MemoryDiagnoser] + public class ValidateSignedHttpRequestAsyncTests + { + private SignedHttpRequestHandler _signedHttpRequestHandler; + private SignedHttpRequestDescriptor _signedHttpRequestDescriptor; + private SignedHttpRequestValidationContext _validationContext; + private string _signedHttpRequest; + + [GlobalSetup] + public void Setup() + { + var requestData = new HttpRequestData(); + _signedHttpRequestHandler = new SignedHttpRequestHandler(); + _signedHttpRequestDescriptor = new SignedHttpRequestDescriptor( + SignedHttpRequestTestUtils.DefaultEncodedAccessToken, + requestData, + SignedHttpRequestTestUtils.DefaultSigningCredentials, + new SignedHttpRequestCreationParameters() + { + CreateM = false, + CreateP = false, + CreateU = false + }); + _signedHttpRequest = _signedHttpRequestHandler.CreateSignedHttpRequest(_signedHttpRequestDescriptor); + _validationContext = new SignedHttpRequestValidationContext( + _signedHttpRequest, + requestData, + SignedHttpRequestTestUtils.DefaultTokenValidationParameters); + } + + [Benchmark] + public async Task SHRHandler_ValidateSignedHttpRequestAsync() => await _signedHttpRequestHandler.ValidateSignedHttpRequestAsync(_validationContext, CancellationToken.None); + } +} diff --git a/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateTokenAsyncTests.cs b/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateTokenAsyncTests.cs index 927097edc1..2ad2b81efd 100644 --- a/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateTokenAsyncTests.cs +++ b/benchmark/Microsoft.IdentityModel.Benchmarks/ValidateTokenAsyncTests.cs @@ -12,28 +12,29 @@ namespace Microsoft.IdentityModel.Benchmarks { [Config(typeof(AntiVirusFriendlyConfig))] [HideColumns("Type", "Job", "WarmupCount", "LaunchCount")] + [MemoryDiagnoser] public class ValidateTokenAsyncTests { - JsonWebTokenHandler jsonWebTokenHandler; - JwtSecurityTokenHandler jwtSecurityTokenHandler; - SecurityTokenDescriptor tokenDescriptor; - string jsonWebToken; - TokenValidationParameters validationParameters; + private JsonWebTokenHandler _jsonWebTokenHandler; + private JwtSecurityTokenHandler _jwtSecurityTokenHandler; + private SecurityTokenDescriptor _tokenDescriptor; + private string _jsonWebToken; + private TokenValidationParameters _validationParameters; [GlobalSetup] public void Setup() { - tokenDescriptor = new SecurityTokenDescriptor + _tokenDescriptor = new SecurityTokenDescriptor { Claims = BenchmarkUtils.SimpleClaims, SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials, }; - jsonWebToken = jsonWebTokenHandler.CreateToken(tokenDescriptor); - validationParameters = new TokenValidationParameters() + _jsonWebToken = _jsonWebTokenHandler.CreateToken(_tokenDescriptor); + _validationParameters = new TokenValidationParameters() { - ValidAudience = "http://Default.Audience.com", + ValidAudience = Default.Audience, ValidateLifetime = true, - ValidIssuer = "http://Default.Issuer.com", + ValidIssuer = Default.Issuer, IssuerSigningKey = KeyingMaterial.JsonWebKeyRsa256SigningCredentials.Key, }; } @@ -41,22 +42,22 @@ public void Setup() [GlobalSetup(Targets = new[] { nameof(JsonWebTokenHandler_ValidateTokenAsync) })] public void JsonWebTokenSetup() { - jsonWebTokenHandler = new JsonWebTokenHandler(); - jsonWebTokenHandler.SetDefaultTimesOnTokenCreation = false; + _jsonWebTokenHandler = new JsonWebTokenHandler(); + _jsonWebTokenHandler.SetDefaultTimesOnTokenCreation = false; } [Benchmark] - public async Task JsonWebTokenHandler_ValidateTokenAsync() => await jsonWebTokenHandler.ValidateTokenAsync(jsonWebToken, validationParameters).ConfigureAwait(false); + public async Task JsonWebTokenHandler_ValidateTokenAsync() => await _jsonWebTokenHandler.ValidateTokenAsync(_jsonWebToken, _validationParameters).ConfigureAwait(false); [GlobalSetup(Targets = new[] { nameof(JwtSecurityTokenHandler_ValidateTokenAsync) })] public void JwtSecurityTokenSetup() { - jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); - jwtSecurityTokenHandler.SetDefaultTimesOnTokenCreation = false; + _jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); + _jwtSecurityTokenHandler.SetDefaultTimesOnTokenCreation = false; } [Benchmark] - public async Task JwtSecurityTokenHandler_ValidateTokenAsync() => await jwtSecurityTokenHandler.ValidateTokenAsync(jsonWebToken, validationParameters).ConfigureAwait(false); + public async Task JwtSecurityTokenHandler_ValidateTokenAsync() => await _jwtSecurityTokenHandler.ValidateTokenAsync(_jsonWebToken, _validationParameters).ConfigureAwait(false); } } diff --git a/benchmark/Microsoft.IdentityModel.Benchmarks/identitymodel.benchmarks.yml b/benchmark/Microsoft.IdentityModel.Benchmarks/identitymodel.benchmarks.yml index 3e68471597..8997e8a3eb 100644 --- a/benchmark/Microsoft.IdentityModel.Benchmarks/identitymodel.benchmarks.yml +++ b/benchmark/Microsoft.IdentityModel.Benchmarks/identitymodel.benchmarks.yml @@ -13,14 +13,47 @@ jobs: arguments: --job {{jobArg}} --filter {{filterArg}} --memory options: benchmarkDotNet: true + +profiles: + windows: + description: INTEL/Windows 28 Cores + arguments: --profile aspnet-citrine-win scenarios: - ValidateToken: + CreateJWE: + application: + job: benchmarks + variables: + filterArg: "*CreateJWETests*" + + CreateSHR: application: - job: "*ValidateTokenAsyncTests*" + job: benchmarks + variables: + filterArg: "*CreateSignedHttpRequestTests*" CreateToken: application: - job: "*CreateTokenTests*" + job: benchmarks + variables: + filterArg: "*CreateTokenTests*" + + ValidateJWE: + application: + job: benchmarks + variables: + filterArg: "*ValidateJWEAsyncTests*" + + ValidateSHR: + application: + job: benchmarks + variables: + filterArg: "*ValidateSignedHttpRequestAsyncTests*" + + ValidateToken: + application: + job: benchmarks + variables: + filterArg: "*ValidateTokenAsyncTests*" diff --git a/test/Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests/Properties/AssemblyInfo.cs b/test/Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests/Properties/AssemblyInfo.cs index 9822268a7b..94e48760ae 100644 --- a/test/Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests/Properties/AssemblyInfo.cs +++ b/test/Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests/Properties/AssemblyInfo.cs @@ -2,7 +2,9 @@ // Licensed under the MIT License. using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [assembly: CLSCompliant(false)] [assembly: ComVisible(false)] +[assembly: InternalsVisibleTo("Microsoft.IdentityModel.Benchmarks, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]