diff --git a/DigitalData.Core.Abstractions/Security/IAsymmetricKey.cs b/DigitalData.Core.Abstractions/Security/IAsymmetricKey.cs index d2ed20b..122fe29 100644 --- a/DigitalData.Core.Abstractions/Security/IAsymmetricKey.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymmetricKey.cs @@ -10,7 +10,5 @@ namespace DigitalData.Core.Abstractions.Security public new string Issuer { get; init; } public new string Audience { get; init; } - - public SecurityKey SecurityKey { get; } } } \ No newline at end of file diff --git a/DigitalData.Core.Abstractions/Security/IAsymmetricPrivateKey.cs b/DigitalData.Core.Abstractions/Security/IAsymmetricPrivateKey.cs index b630732..d5ec4ca 100644 --- a/DigitalData.Core.Abstractions/Security/IAsymmetricPrivateKey.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymmetricPrivateKey.cs @@ -7,9 +7,5 @@ namespace DigitalData.Core.Abstractions.Security public bool IsEncrypted { get; init; } IAsymmetricPublicKey PublicKey { get; } - - PrivateKeyTokenDescriptor? TokenDescriptor { get; init; } - - SigningCredentials CreateSigningCredentials(string algorithm = SecurityAlgorithms.RsaSha256, string? digest = null); } } \ No newline at end of file diff --git a/DigitalData.Core.Abstractions/Security/IAsymmetricTokenDescriptor.cs b/DigitalData.Core.Abstractions/Security/IAsymmetricTokenDescriptor.cs new file mode 100644 index 0000000..a168786 --- /dev/null +++ b/DigitalData.Core.Abstractions/Security/IAsymmetricTokenDescriptor.cs @@ -0,0 +1,13 @@ +using Microsoft.IdentityModel.Tokens; + +namespace DigitalData.Core.Abstractions.Security +{ + public interface IAsymmetricTokenDescriptor : IAsymmetricPrivateKey, IUniqueSecurityContext + { + string? ApiRoute { get; } + + SecurityKey SecurityKey { get; } + + SigningCredentials SigningCredentials { get; } + } +} \ No newline at end of file diff --git a/DigitalData.Core.Security/Config/CryptographParams.cs b/DigitalData.Core.Security/Config/CryptographParams.cs index f9f2cf0..d6dd136 100644 --- a/DigitalData.Core.Security/Config/CryptographParams.cs +++ b/DigitalData.Core.Security/Config/CryptographParams.cs @@ -41,6 +41,8 @@ namespace DigitalData.Core.Security.Config public IEnumerable Decryptors { get; init; } = new List(); + public IEnumerable TokenDescriptors { get; init; } = new List(); + public RSADecryptor? VaultDecryptor { get; init; } public CryptographParams() diff --git a/DigitalData.Core.Security/Config/MappingProfile.cs b/DigitalData.Core.Security/Config/MappingProfile.cs index 8ed0860..1bbbf6d 100644 --- a/DigitalData.Core.Security/Config/MappingProfile.cs +++ b/DigitalData.Core.Security/Config/MappingProfile.cs @@ -8,7 +8,7 @@ namespace DigitalData.Core.Security.Config { public MappingProfile() { - CreateMap(); + CreateMap(); } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptograph.cs b/DigitalData.Core.Security/Cryptograph.cs index 271a209..8483455 100644 --- a/DigitalData.Core.Security/Cryptograph.cs +++ b/DigitalData.Core.Security/Cryptograph.cs @@ -19,7 +19,7 @@ namespace DigitalData.Core.Security public IEnumerable Encryptors => _lazyEncryptors.Value; - public IEnumerable TokenDescriptions { get; init; } = new List(); + public IEnumerable TokenDescriptors { get; init; } = new List(); public Cryptograph(IOptions options, ILogger? logger = null) : base(options) { diff --git a/DigitalData.Core.Security/Extension.cs b/DigitalData.Core.Security/Extension.cs index 347c622..f767b74 100644 --- a/DigitalData.Core.Security/Extension.cs +++ b/DigitalData.Core.Security/Extension.cs @@ -83,7 +83,7 @@ namespace DigitalData.Core.Security /// The instance to be mapped. /// A instance populated with the mapped values. /// Thrown if or is null. - internal static SecurityTokenDescriptor Map(this IMapper mapper, PrivateKeyTokenDescriptor description) + internal static SecurityTokenDescriptor Map(this IMapper mapper, IAsymmetricTokenDescriptor description) => mapper.Map(description, new SecurityTokenDescriptor()); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/RSAKey/RSAKeyBase.cs b/DigitalData.Core.Security/RSAKey/RSAKeyBase.cs index d076c88..1337015 100644 --- a/DigitalData.Core.Security/RSAKey/RSAKeyBase.cs +++ b/DigitalData.Core.Security/RSAKey/RSAKeyBase.cs @@ -1,6 +1,5 @@ using DigitalData.Core.Abstractions.Security; using Microsoft.IdentityModel.Tokens; -using System.Reflection; using System.Security.Cryptography; namespace DigitalData.Core.Security.RSAKey @@ -14,15 +13,11 @@ namespace DigitalData.Core.Security.RSAKey public string Issuer { get; init; } = string.Empty; public string Audience { get; init; } = string.Empty; - - private readonly Lazy _lazyRsaSecurityKey; - - public SecurityKey SecurityKey => _lazyRsaSecurityKey.Value; - + #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. internal RSAKeyBase() { - _lazyRsaSecurityKey = new(() => new RsaSecurityKey(RSA)); + } #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. } diff --git a/DigitalData.Core.Security/RSAKey/RSAPrivateKey.cs b/DigitalData.Core.Security/RSAKey/RSAPrivateKey.cs index a0901a4..189188c 100644 --- a/DigitalData.Core.Security/RSAKey/RSAPrivateKey.cs +++ b/DigitalData.Core.Security/RSAKey/RSAPrivateKey.cs @@ -28,29 +28,12 @@ namespace DigitalData.Core.Security.RSAKey public IAsymmetricPublicKey PublicKey => _lazyPublicKey.Value; - private PrivateKeyTokenDescriptor? _tokenDescriptor; - - private readonly Lazy _descriptorInitiator; - - public PrivateKeyTokenDescriptor? TokenDescriptor { get => _descriptorInitiator.Value; init => _tokenDescriptor = value; } - public RSAPrivateKey() { _lazyPublicKey = new(() => new RSAPublicKey() { Content = RSA.ExportRSAPublicKeyPem() }); - - _descriptorInitiator = new(() => - { - if(_tokenDescriptor is not null) - { - _tokenDescriptor.Issuer = Issuer; - _tokenDescriptor.Audience = Audience; - _tokenDescriptor.SigningCredentials = CreateSigningCredentials(); - } - return _tokenDescriptor; - }); } internal void SetPem(string pem) @@ -71,8 +54,5 @@ namespace DigitalData.Core.Security.RSAKey } private InvalidOperationException PemIsNullException => new($"Content is null or empty. Issuer: {Issuer}, Audience: {Audience}."); - - public SigningCredentials CreateSigningCredentials(string algorithm = SecurityAlgorithms.RsaSha256, string? digest = null) - => digest is null ? new(SecurityKey, algorithm) : new(SecurityKey, algorithm, digest); } } \ No newline at end of file diff --git a/DigitalData.Core.Abstractions/Security/PrivateKeyTokenDescriptor.cs b/DigitalData.Core.Security/RSAKey/RSATokenDescriptor.cs similarity index 79% rename from DigitalData.Core.Abstractions/Security/PrivateKeyTokenDescriptor.cs rename to DigitalData.Core.Security/RSAKey/RSATokenDescriptor.cs index fd9638a..bec51c3 100644 --- a/DigitalData.Core.Abstractions/Security/PrivateKeyTokenDescriptor.cs +++ b/DigitalData.Core.Security/RSAKey/RSATokenDescriptor.cs @@ -1,24 +1,21 @@ -using Microsoft.IdentityModel.Tokens; +using DigitalData.Core.Abstractions.Security; +using Microsoft.IdentityModel.Tokens; +using System.Security.Cryptography; -namespace DigitalData.Core.Abstractions.Security +namespace DigitalData.Core.Security.RSAKey { /// /// Contains some information which used to create a security token. Designed to abstract /// - public class PrivateKeyTokenDescriptor : IUniqueSecurityContext + public class RSATokenDescriptor : RSAPrivateKey, IAsymmetricTokenDescriptor { public string? ApiRoute { get; init; } - /// - /// Gets or sets the value of the 'audience' claim. - /// -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public string Audience { get; set; } - + #region SecurityTokenDescriptor Map /// /// Defines the compression algorithm that will be used to compress the JWT token payload. /// - public string CompressionAlgorithm { get; set; } + public string CompressionAlgorithm { get; set; } /// /// Gets or sets the used to create a encrypted security token. @@ -30,11 +27,6 @@ namespace DigitalData.Core.Abstractions.Security /// public DateTime? Expires { get; set; } - /// - /// Gets or sets the issuer of this . - /// - public string Issuer { get; set; } - /// /// Gets or sets the time the security token was issued. This value should be in UTC. /// @@ -76,19 +68,36 @@ namespace DigitalData.Core.Abstractions.Security /// /// Gets or sets the used to create a security token. /// - public SigningCredentials SigningCredentials { get; set; } -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public SigningCredentials SigningCredentials => _lazySigningCredentials.Value; + #endregion SecurityTokenDescriptor + + private readonly Lazy _lazyRsaSecurityKey; + + public SecurityKey SecurityKey => _lazyRsaSecurityKey.Value; + + private readonly Lazy _lazySigningCredentials; /// /// Specifies the signature algorithm to be applied to the . /// Default is . /// - public string SigningAlgorithm { get; internal set; } = SecurityAlgorithms.RsaSha256; + public string SigningAlgorithm { get; init; } = SecurityAlgorithms.RsaSha256; /// /// Optionally specifies the digest algorithm to be applied during the signing process for the . /// If not provided, the default algorithm is used. /// public string? SigningDigest { get; init; } + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public RSATokenDescriptor() +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + { + _lazyRsaSecurityKey = new(() => new RsaSecurityKey(RSA)); + + _lazySigningCredentials = new(() => SigningDigest is null + ? new(SecurityKey, SigningAlgorithm) + : new(SecurityKey, SigningAlgorithm, SigningDigest)); + } } -} \ No newline at end of file +}