feat: Implement API client and token models with hashing and JWT authentication
- Added ApiClientModel and ApiTokenModel for managing API clients and tokens. - Introduced ConfigurationDefinitionModel and ConfigurationValueModel for configuration management. - Created CredentialSecretModel for storing credential secrets. - Developed DeploymentArtifactModel and DeploymentBatchModel for deployment management. - Enhanced DeploymentTargetModel and DeploymentTemplateSelectionModel to support template revisions. - Added TemplateRevisionModel and TemplateVersionModel for versioning templates. - Implemented ApiClientSecretHasher for secure secret hashing. - Created ApiTokenService for generating and validating JWT tokens. - Updated QueueJobService to handle deployment requests with artifacts. - Configured authentication settings in appsettings.json for JWT and Negotiate authentication.
This commit is contained in:
58
Services/ApiClientSecretHasher.cs
Normal file
58
Services/ApiClientSecretHasher.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Services
|
||||
{
|
||||
public static class ApiClientSecretHasher
|
||||
{
|
||||
private const int SaltSize = 16;
|
||||
private const int KeySize = 32;
|
||||
private const int DefaultIterations = 100_000;
|
||||
|
||||
public static string HashSecret(string secret)
|
||||
{
|
||||
var salt = RandomNumberGenerator.GetBytes(SaltSize);
|
||||
var hash = Rfc2898DeriveBytes.Pbkdf2(secret, salt, DefaultIterations, HashAlgorithmName.SHA256, KeySize);
|
||||
|
||||
return string.Join(
|
||||
'.',
|
||||
"PBKDF2-SHA256",
|
||||
DefaultIterations.ToString(),
|
||||
Convert.ToBase64String(salt),
|
||||
Convert.ToBase64String(hash));
|
||||
}
|
||||
|
||||
public static bool VerifySecret(string secret, string storedHash)
|
||||
{
|
||||
var parts = storedHash.Split('.');
|
||||
if (parts.Length != 4 || parts[0] != "PBKDF2-SHA256")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!int.TryParse(parts[1], out var iterations))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var salt = Convert.FromBase64String(parts[2]);
|
||||
var expectedHash = Convert.FromBase64String(parts[3]);
|
||||
var actualHash = Rfc2898DeriveBytes.Pbkdf2(secret, salt, iterations, HashAlgorithmName.SHA256, expectedHash.Length);
|
||||
|
||||
return CryptographicOperations.FixedTimeEquals(actualHash, expectedHash);
|
||||
}
|
||||
|
||||
internal static string HashSecretForDemoData(string secret, string saltText)
|
||||
{
|
||||
var salt = System.Text.Encoding.UTF8.GetBytes(saltText);
|
||||
Array.Resize(ref salt, SaltSize);
|
||||
var hash = Rfc2898DeriveBytes.Pbkdf2(secret, salt, DefaultIterations, HashAlgorithmName.SHA256, KeySize);
|
||||
|
||||
return string.Join(
|
||||
'.',
|
||||
"PBKDF2-SHA256",
|
||||
DefaultIterations.ToString(),
|
||||
Convert.ToBase64String(salt),
|
||||
Convert.ToBase64String(hash));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user