Skip to content

Commit

Permalink
Decouple benchmark tests from test projects.
Browse files Browse the repository at this point in the history
Adjusted tests to use the same claims, keys and more realistic settings in runs.
  • Loading branch information
Brent Schmaltz authored and brentschmaltz committed Nov 22, 2023
1 parent e25592a commit 21d2f6d
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 96 deletions.
109 changes: 99 additions & 10 deletions benchmark/Microsoft.IdentityModel.Benchmarks/BenchmarkUtils.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,113 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.TestUtils;
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;

namespace Microsoft.IdentityModel.Benchmarks
{
public class BenchmarkUtils
{
public static Dictionary<string, object> SimpleClaims
public const string Issuer = "http://www.contoso.com";

public const string Audience = "http://www.contoso.com/protected";

private static RSA _rsa;
private static SymmetricSecurityKey _symmetricKey;

public static RSA RSA
{
get
{
if (_rsa == null)
{
_rsa = RSA.Create();
_rsa.KeySize = 2048;
}

return _rsa;
}
}

public static RSAParameters RsaParameters => RSA.ExportParameters(true);

public static RSAParameters RsaParametersPublic => RSA.ExportParameters(false);

public static RsaSecurityKey RsaSecurityKey => new(RsaParameters) { KeyId = "RsaPrivate" };

public static RsaSecurityKey RsaSecurityKeyPublic => new(RsaParametersPublic) { KeyId = "RsaPublic" };

public static Dictionary<string, object> Claims
{
get
{
DateTime now = DateTime.UtcNow;
return new Dictionary<string, object>()
{
{ "role", new List<string>() { "role1", "Developer", "Sales"} },
{ JwtRegisteredClaimNames.Email, "[email protected]" },
{ JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(now + TimeSpan.FromDays(1)) },
{ JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(now) },
{ JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(now) },
{ JwtRegisteredClaimNames.GivenName, "Bob" },
{ JwtRegisteredClaimNames.Iss, Issuer },
{ JwtRegisteredClaimNames.Aud, Audience }
};
}
}

public static SigningCredentials SigningCredentialsRsaSha256 => new(RsaSecurityKey, SecurityAlgorithms.RsaSha256, SecurityAlgorithms.Sha256);

public static EncryptingCredentials EncryptingCredentialsAes256Sha512 => new(SymmetricEncryptionKey512, "dir", SecurityAlgorithms.Aes256CbcHmacSha512);

public static SymmetricSecurityKey SymmetricEncryptionKey512
{
get
{
_symmetricKey ??= new SymmetricSecurityKey(SHA512.Create().ComputeHash(Guid.NewGuid().ToByteArray()));
return _symmetricKey;
}
}

public static string CreateCnfClaim(RsaSecurityKey key, string algorithm)
{
get => new Dictionary<string, object>()
return "{\"jwk\":" + CreateJwkClaim(key, algorithm) + "}";
}

public static string CreateJwkClaim(RsaSecurityKey key, string algorithm)
{
RSAParameters rsaParameters = ((key.Rsa == null) ? key.Parameters : key.Rsa.ExportParameters(includePrivateParameters: false));
return "{\"kty\":\"RSA\",\"n\":\"" +
Base64UrlEncoder.Encode(rsaParameters.Modulus) +
"\",\"e\":\"" +
Base64UrlEncoder.Encode(rsaParameters.Exponent) +
"\",\"alg\":\"" +
algorithm +
"\",\"kid\":\"" +
key.KeyId +
"\"}";
}

public static string CreateAccessTokenWithCnf()
{
Dictionary<string, object> claims = new Dictionary<string, object>(Claims);
claims.Add("cnf", CreateCnfClaim(RsaSecurityKeyPublic, SecurityAlgorithms.RsaSha256));
return new JsonWebTokenHandler().CreateToken(new SecurityTokenDescriptor
{
{ "role", new List<string>() { "role1", "Developer", "Sales"} },
{ "email", "[email protected]" },
{ "exp", EpochTime.GetIntDate(Default.Expires).ToString() },
{ "nbf", EpochTime.GetIntDate(Default.NotBefore).ToString() },
{ "iat", EpochTime.GetIntDate(Default.IssueInstant).ToString() }
};
SigningCredentials = SigningCredentialsRsaSha256,
Claims = claims,
TokenType = JwtHeaderParameterNames.Jwk
});
}

public static HttpRequestData HttpRequestData => new()
{
Method = "GET",
Uri = new Uri("https://www.relyingparty.com")
};
}
}
10 changes: 4 additions & 6 deletions benchmark/Microsoft.IdentityModel.Benchmarks/CreateJWETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
// 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
Expand All @@ -26,10 +24,9 @@ public void Setup()
_jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
_tokenDescriptor = new SecurityTokenDescriptor
{
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
EncryptingCredentials = KeyingMaterial.DefaultSymmetricEncryptingCreds_Aes256_Sha512_512,
Subject = new ClaimsIdentity(Default.PayloadClaims),
TokenType = "TokenType"
SigningCredentials = BenchmarkUtils.SigningCredentialsRsaSha256,
EncryptingCredentials = BenchmarkUtils.EncryptingCredentialsAes256Sha512,
Claims = BenchmarkUtils.Claims
};
}

Expand All @@ -38,5 +35,6 @@ public void Setup()

[Benchmark]
public string JwtSecurityTokenHandler_CreateJWE() => _jwtSecurityTokenHandler.CreateEncodedJwt(_tokenDescriptor);

}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using Microsoft.IdentityModel.Protocols.SignedHttpRequest;
using Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.SignedHttpRequest;
using Microsoft.IdentityModel.Tokens;

namespace Microsoft.IdentityModel.Benchmarks
{
Expand All @@ -20,19 +22,18 @@ public void Setup()
{
_signedHttpRequestHandler = new SignedHttpRequestHandler();
_signedHttpRequestDescriptor = new SignedHttpRequestDescriptor(
SignedHttpRequestTestUtils.DefaultEncodedAccessToken,
new HttpRequestData(),
SignedHttpRequestTestUtils.DefaultSigningCredentials,
BenchmarkUtils.CreateAccessTokenWithCnf(),
BenchmarkUtils.HttpRequestData,
BenchmarkUtils.SigningCredentialsRsaSha256,
new SignedHttpRequestCreationParameters()
{
CreateM = false,
CreateM = true,
CreateP = false,
CreateU = false
CreateU = true
});
}

[Benchmark]
public string SHRHandler_CreateSignedHttpRequest() => _signedHttpRequestHandler.CreateSignedHttpRequest(_signedHttpRequestDescriptor);

}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Security.Claims;
using BenchmarkDotNet.Attributes;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.TestUtils;
using Microsoft.IdentityModel.Tokens;

namespace Microsoft.IdentityModel.Benchmarks
Expand All @@ -22,13 +20,12 @@ public void Setup()
_jsonWebTokenHandler = new JsonWebTokenHandler();
_tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(Default.PayloadClaims),
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
Claims = BenchmarkUtils.Claims,
SigningCredentials = BenchmarkUtils.SigningCredentialsRsaSha256,
};
}

[Benchmark]
public string JsonWebTokenHandler_CreateToken() => _jsonWebTokenHandler.CreateToken(_tokenDescriptor);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<AssemblyName>Microsoft.IdentityModel.Benchmarks</AssemblyName>
<PackageId>Microsoft.IdentityModel.Benchmarks</PackageId>
<OutputType>Exe</OutputType>
<TargetFrameworks Condition="'$(TargetNet8)' == 'True'">net6.0; net8.0</TargetFrameworks>
<TargetFrameworks Condition="'$(TargetNet8)' == 'True'">net6.0;net8.0</TargetFrameworks>
<TargetFrameworks Condition="'$(TargetNet8)' != 'True'">net6.0</TargetFrameworks>
<SignAssembly>True</SignAssembly>
<DelaySign>True</DelaySign>
Expand All @@ -21,12 +21,10 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\test\Microsoft.IdentityModel.TestUtils\Microsoft.IdentityModel.TestUtils.csproj" />
<ProjectReference Include="..\..\src\Microsoft.IdentityModel.JsonWebTokens\Microsoft.IdentityModel.JsonWebTokens.csproj" />
<ProjectReference Include="..\..\src\Microsoft.IdentityModel.Tokens\Microsoft.IdentityModel.Tokens.csproj" />
<ProjectReference Include="..\..\src\System.IdentityModel.Tokens.Jwt\System.IdentityModel.Tokens.Jwt.csproj" />
<ProjectReference Include="..\..\src\Microsoft.IdentityModel.Protocols.SignedHttpRequest\Microsoft.IdentityModel.Protocols.SignedHttpRequest.csproj" />
<ProjectReference Include="..\..\test\Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests\Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests.csproj" />
</ItemGroup>

</Project>
34 changes: 34 additions & 0 deletions benchmark/Microsoft.IdentityModel.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

//#define DEBUG_TESTS

#if DEBUG_TESTS
using Microsoft.IdentityModel.Protocols.SignedHttpRequest;
using Microsoft.IdentityModel.Tokens;
#endif
using BenchmarkDotNet.Running;

namespace Microsoft.IdentityModel.Benchmarks
Expand All @@ -9,7 +15,35 @@ public static class Program
{
public static void Main(string[] args)
{
#if DEBUG_TESTS
DebugThroughTests();
#endif
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
}

#if DEBUG_TESTS
private static void DebugThroughTests()
{
CreateJWETests createJWETests = new CreateJWETests();
createJWETests.Setup();
string jwe = createJWETests.JsonWebTokenHandler_CreateJWE();

CreateSignedHttpRequestTests createSignedHttpRequestTests = new CreateSignedHttpRequestTests();
createSignedHttpRequestTests.Setup();
string shr = createSignedHttpRequestTests.SHRHandler_CreateSignedHttpRequest();

CreateTokenTests createTokenTests = new CreateTokenTests();
createTokenTests.Setup();
string jws = createTokenTests.JsonWebTokenHandler_CreateToken();

ValidateTokenAsyncTests validateTokenAsyncTests = new ValidateTokenAsyncTests();
validateTokenAsyncTests.Setup();
TokenValidationResult tokenValidationResult = validateTokenAsyncTests.JsonWebTokenHandler_ValidateTokenAsync().Result;

ValidateSignedHttpRequestAsyncTests validateSignedHttpRequestAsyncTests = new ValidateSignedHttpRequestAsyncTests();
validateSignedHttpRequestAsyncTests.Setup();
SignedHttpRequestValidationResult signedHttpRequestValidationResult = validateSignedHttpRequestAsyncTests.SHRHandler_ValidateSignedHttpRequestAsync().Result;
}
#endif
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// 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;
using BenchmarkDotNet.Attributes;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;

namespace Microsoft.IdentityModel.Benchmarks
{
Expand All @@ -19,8 +18,7 @@ public class ValidateJWEAsyncTests
private JsonWebTokenHandler _jsonWebTokenHandler;
private JwtSecurityTokenHandler _jwtSecurityTokenHandler;
private SecurityTokenDescriptor _tokenDescriptor;
private string _jweFromJsonHandler;
private string _jweFromJwtHandler;
private string _jwe;
private TokenValidationParameters _validationParameters;

[GlobalSetup]
Expand All @@ -30,26 +28,26 @@ public void Setup()
_jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
_tokenDescriptor = new SecurityTokenDescriptor
{
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
EncryptingCredentials = KeyingMaterial.DefaultSymmetricEncryptingCreds_Aes256_Sha512_512,
Subject = new ClaimsIdentity(Default.PayloadClaims),
TokenType = "TokenType"
SigningCredentials = BenchmarkUtils.SigningCredentialsRsaSha256,
EncryptingCredentials = BenchmarkUtils.EncryptingCredentialsAes256Sha512,
Claims = BenchmarkUtils.Claims,
TokenType = JsonWebTokens.JwtHeaderParameterNames.Jwk
};
_jweFromJsonHandler = _jsonWebTokenHandler.CreateToken(_tokenDescriptor);
_jweFromJwtHandler = _jwtSecurityTokenHandler.CreateEncodedJwt(_tokenDescriptor);

_jwe = _jsonWebTokenHandler.CreateToken(_tokenDescriptor);
_validationParameters = new TokenValidationParameters
{
IssuerSigningKey = KeyingMaterial.JsonWebKeyRsa256SigningCredentials.Key,
TokenDecryptionKey = KeyingMaterial.DefaultSymmetricSecurityKey_512,
ValidAudience = Default.Audience,
ValidIssuer = Default.Issuer
IssuerSigningKey = BenchmarkUtils.SigningCredentialsRsaSha256.Key,
TokenDecryptionKey = BenchmarkUtils.SymmetricEncryptionKey512,
ValidAudience = BenchmarkUtils.Audience,
ValidIssuer = BenchmarkUtils.Issuer
};
}

[Benchmark]
public async Task<TokenValidationResult> JsonWebTokenHandler_ValidateJWEAsync() => await _jsonWebTokenHandler.ValidateTokenAsync(_jweFromJsonHandler, _validationParameters);
public async Task<TokenValidationResult> JsonWebTokenHandler_ValidateJWEAsync() => await _jsonWebTokenHandler.ValidateTokenAsync(_jwe, _validationParameters);

[Benchmark]
public ClaimsPrincipal JwtSecurityTokenHandler_ValidateJWEAsync() => _jwtSecurityTokenHandler.ValidateToken(_jweFromJwtHandler, _validationParameters, out _);
public ClaimsPrincipal JwtSecurityTokenHandler_ValidateJWEAsync() => _jwtSecurityTokenHandler.ValidateToken(_jwe, _validationParameters, out SecurityToken _securityToken);
}
}
Loading

0 comments on commit 21d2f6d

Please sign in to comment.