diff --git a/DigitalData.Core.Abstractions.Security/Common/IUniqueSecurityContext.cs b/DigitalData.Core.Abstractions.Security/Common/IUniqueSecurityContext.cs
new file mode 100644
index 0000000..f13f02e
--- /dev/null
+++ b/DigitalData.Core.Abstractions.Security/Common/IUniqueSecurityContext.cs
@@ -0,0 +1,23 @@
+namespace DigitalData.Core.Abstractions.Security.Common;
+
+///
+/// Represents a unique security context that identifies an issuer and an audience.
+///
+public interface IUniqueSecurityContext
+{
+ ///
+ /// Gets the issuer identifier for this security context.
+ ///
+ ///
+ /// The issuer typically represents the entity that issues a token or a cryptographic key.
+ ///
+ string Issuer { get; }
+
+ ///
+ /// Gets the audience identifier for this security context.
+ ///
+ ///
+ /// The audience typically represents the intended recipient or target of a token or cryptographic operation.
+ ///
+ string Audience { get; }
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/Extensions/SecurityExtensions.cs b/DigitalData.Core.Abstractions.Security/Extensions/SecurityExtensions.cs
new file mode 100644
index 0000000..d1a8955
--- /dev/null
+++ b/DigitalData.Core.Abstractions.Security/Extensions/SecurityExtensions.cs
@@ -0,0 +1,64 @@
+using DigitalData.Core.Abstractions.Security.Common;
+using DigitalData.Core.Abstractions.Security.Key;
+using DigitalData.Core.Abstractions.Security.Services;
+using Microsoft.IdentityModel.Tokens;
+using System.Text;
+
+namespace DigitalData.Core.Abstractions.Security.Extensions;
+
+public static class SecurityExtensions
+{
+ #region Unique Security Context
+ public static IEnumerable GetByIssuer(this IEnumerable contextes, string issuer) where TUniqueSecurityContext : IUniqueSecurityContext
+ => contextes.Where(c => c.Issuer == issuer);
+
+ public static IEnumerable GetByAudience(this IEnumerable contextes, string audience) where TUniqueSecurityContext : IUniqueSecurityContext
+ => contextes.Where(c => c.Audience == audience);
+
+ public static TUniqueSecurityContext Get(this IEnumerable contextes, string issuer, string audience) where TUniqueSecurityContext : IUniqueSecurityContext
+ => contextes.Where(c => c.Issuer == issuer && c.Audience == audience).SingleOrDefault()
+ ?? throw new InvalidOperationException($"Exactly one {typeof(TUniqueSecurityContext).Name} must exist with Issuer: '{issuer}' and Audience: '{audience}'.");
+
+ public static bool TryGet(this IEnumerable contextes, string issuer, string audience, out TUniqueSecurityContext context) where TUniqueSecurityContext : IUniqueSecurityContext
+ {
+#pragma warning disable CS8601 // Possible null reference assignment.
+ context = contextes.SingleOrDefault(c => c.Issuer == issuer && c.Audience == audience);
+#pragma warning restore CS8601 // Possible null reference assignment.
+ return context is not null;
+ }
+
+ public static TUniqueSecurityContext Match(this IEnumerable contextes, IUniqueSecurityContext lookupContext) where TUniqueSecurityContext : IUniqueSecurityContext
+ => contextes.Get(lookupContext.Issuer, lookupContext.Audience);
+
+ public static bool TryMatch(this IEnumerable contextes, IUniqueSecurityContext lookupContext, out TUniqueSecurityContext context) where TUniqueSecurityContext : IUniqueSecurityContext
+ => contextes.TryGet(lookupContext.Issuer, lookupContext.Audience, out context);
+ #endregion Unique Security Context
+
+ #region De/serilization
+ internal static byte[] Base64ToByte(this string base64String) => Convert.FromBase64String(base64String);
+
+ internal static string BytesToString(this byte[] bytes) => Encoding.UTF8.GetString(bytes);
+
+ internal static string ToBase64String(this byte[] bytes) => Convert.ToBase64String(bytes);
+
+ internal static byte[] ToBytes(this string str) => Encoding.UTF8.GetBytes(str);
+
+ public static string Decrypt(this IAsymmetricDecryptor decryptor, string data) => decryptor
+ .Decrypt(data.Base64ToByte()).BytesToString();
+ #endregion De/serilization
+
+ #region Asymmetric Encryptor
+ public static string Encrypt(this IAsymmetricEncryptor encryptor, string data) => encryptor.Encrypt(data.ToBytes()).ToBase64String();
+ #endregion Asymmetric Encryptor
+
+ #region Jwt Signature Handler
+ public static string WriteToken(this IJwtSignatureHandler handler, SecurityTokenDescriptor descriptor)
+ => handler.WriteToken(handler.CreateToken(descriptor));
+
+ public static string WriteToken(this IJwtSignatureHandler handler, TPrincipal subject, IAsymmetricTokenDescriptor descriptor)
+ => handler.WriteToken(handler.CreateToken(subject: subject, descriptor: descriptor));
+
+ public static string WriteToken(this IJwtSignatureHandler handler, TPrincipal subject, string issuer, string audience)
+ => handler.WriteToken(handler.CreateToken(subject: subject, issuer: issuer, audience: audience));
+ #endregion Jwt Signature Handler
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/IAsymmetricDecryptor.cs b/DigitalData.Core.Abstractions.Security/IAsymmetricDecryptor.cs
deleted file mode 100644
index 66a45a4..0000000
--- a/DigitalData.Core.Abstractions.Security/IAsymmetricDecryptor.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace DigitalData.Core.Abstractions.Security
-{
- public interface IAsymmetricDecryptor : IAsymmetricPrivateKey
- {
- byte[] Decrypt(byte[] data);
-
- IAsymmetricEncryptor Encryptor { get; }
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/IAsymmetricEncryptor.cs b/DigitalData.Core.Abstractions.Security/IAsymmetricEncryptor.cs
deleted file mode 100644
index c94539a..0000000
--- a/DigitalData.Core.Abstractions.Security/IAsymmetricEncryptor.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace DigitalData.Core.Abstractions.Security
-{
- public interface IAsymmetricEncryptor : IAsymmetricPublicKey
- {
- byte[] Encrypt(byte[] data);
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/IAsymmetricKey.cs b/DigitalData.Core.Abstractions.Security/IAsymmetricKey.cs
deleted file mode 100644
index f0a33c7..0000000
--- a/DigitalData.Core.Abstractions.Security/IAsymmetricKey.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace DigitalData.Core.Abstractions.Security
-{
- public interface IAsymmetricKey
- {
- string? Id { get; }
-
- string Content { get; }
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/IAsymmetricPrivateKey.cs b/DigitalData.Core.Abstractions.Security/IAsymmetricPrivateKey.cs
deleted file mode 100644
index c8eae1e..0000000
--- a/DigitalData.Core.Abstractions.Security/IAsymmetricPrivateKey.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace DigitalData.Core.Abstractions.Security
-{
- public interface IAsymmetricPrivateKey : IAsymmetricKey
- {
- bool IsEncrypted { get; }
-
- IAsymmetricPublicKey PublicKey { get; }
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/IAsymmetricPublicKey.cs b/DigitalData.Core.Abstractions.Security/IAsymmetricPublicKey.cs
deleted file mode 100644
index 7d6b4c8..0000000
--- a/DigitalData.Core.Abstractions.Security/IAsymmetricPublicKey.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace DigitalData.Core.Abstractions.Security
-{
- public interface IAsymmetricPublicKey : IAsymmetricKey
- {
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/IAsymmetricTokenDescriptor.cs b/DigitalData.Core.Abstractions.Security/IAsymmetricTokenDescriptor.cs
deleted file mode 100644
index c75ef76..0000000
--- a/DigitalData.Core.Abstractions.Security/IAsymmetricTokenDescriptor.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using Microsoft.IdentityModel.Tokens;
-
-namespace DigitalData.Core.Abstractions.Security
-{
- ///
- /// Contains some information which used to create a security token. Designed to abstract
- ///
- public interface IAsymmetricTokenDescriptor : IAsymmetricPrivateKey, IUniqueSecurityContext
- {
- IAsymmetricTokenValidator Validator { get; }
-
- TimeSpan Lifetime { get; init; }
-
- #region SecurityTokenDescriptor Map
- ///
- /// Defines the compression algorithm that will be used to compress the JWT token payload.
- ///
- string CompressionAlgorithm { get; }
-
- ///
- /// Gets or sets the used to create a encrypted security token.
- ///
- EncryptingCredentials EncryptingCredentials { get; }
-
- ///
- /// Gets or sets the value of the 'expiration' claim. This value should be in UTC.
- ///
- DateTime? Expires { get; }
-
- ///
- /// Gets or sets the time the security token was issued. This value should be in UTC.
- ///
- DateTime? IssuedAt { get; }
-
- ///
- /// Gets or sets the notbefore time for the security token. This value should be in UTC.
- ///
- DateTime? NotBefore { get; }
-
- ///
- /// Gets or sets the token type.
- /// If provided, this will be added as the value for the 'typ' header parameter. In the case of a JWE, this will be added to both the inner (JWS) and the outer token (JWE) header. By default, the value used is 'JWT'.
- /// If also contains 'typ' header claim value, it will override the TokenType provided here.
- /// This value is used only for JWT tokens and not for SAML/SAML2 tokens
- ///
- string TokenType { get; }
-
- ///
- /// Gets or sets the which contains any custom header claims that need to be added to the JWT token header.
- /// The 'alg', 'kid', 'x5t', 'enc', and 'zip' claims are added by default based on the ,
- /// , and/or provided and SHOULD NOT be included in this dictionary as this
- /// will result in an exception being thrown.
- /// These claims are only added to the outer header (in case of a JWE).
- ///
- IDictionary AdditionalHeaderClaims { get; }
-
- ///
- /// Gets or sets the which contains any custom header claims that need to be added to the inner JWT token header.
- /// The 'alg', 'kid', 'x5t', 'enc', and 'zip' claims are added by default based on the ,
- /// , and/or provided and SHOULD NOT be included in this dictionary as this
- /// will result in an exception being thrown.
- ///
- /// For JsonWebTokenHandler, these claims are merged with while adding to the inner JWT header.
- ///
- ///
- IDictionary AdditionalInnerHeaderClaims { get; }
-
- ///
- /// Gets or sets the used to create a security token.
- ///
- SigningCredentials SigningCredentials { get; }
- #endregion SecurityTokenDescriptor
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/IAsymmetricTokenValidator.cs b/DigitalData.Core.Abstractions.Security/IAsymmetricTokenValidator.cs
deleted file mode 100644
index e6f76d0..0000000
--- a/DigitalData.Core.Abstractions.Security/IAsymmetricTokenValidator.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Microsoft.IdentityModel.Tokens;
-
-namespace DigitalData.Core.Abstractions.Security
-{
- public interface IAsymmetricTokenValidator : IAsymmetricPublicKey
- {
- SecurityKey SecurityKey { get; }
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/IUniqueSecurityContext.cs b/DigitalData.Core.Abstractions.Security/IUniqueSecurityContext.cs
deleted file mode 100644
index 6f8869d..0000000
--- a/DigitalData.Core.Abstractions.Security/IUniqueSecurityContext.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-namespace DigitalData.Core.Abstractions.Security
-{
- ///
- /// Represents a unique security context that identifies an issuer and an audience.
- ///
- public interface IUniqueSecurityContext
- {
- ///
- /// Gets the issuer identifier for this security context.
- ///
- ///
- /// The issuer typically represents the entity that issues a token or a cryptographic key.
- ///
- string Issuer { get; }
-
- ///
- /// Gets the audience identifier for this security context.
- ///
- ///
- /// The audience typically represents the intended recipient or target of a token or cryptographic operation.
- ///
- string Audience { get; }
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/Key/IAsymmetricDecryptor.cs b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricDecryptor.cs
new file mode 100644
index 0000000..2154079
--- /dev/null
+++ b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricDecryptor.cs
@@ -0,0 +1,8 @@
+namespace DigitalData.Core.Abstractions.Security.Key;
+
+public interface IAsymmetricDecryptor : IAsymmetricPrivateKey
+{
+ byte[] Decrypt(byte[] data);
+
+ IAsymmetricEncryptor Encryptor { get; }
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/Key/IAsymmetricEncryptor.cs b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricEncryptor.cs
new file mode 100644
index 0000000..afa0298
--- /dev/null
+++ b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricEncryptor.cs
@@ -0,0 +1,6 @@
+namespace DigitalData.Core.Abstractions.Security.Key;
+
+public interface IAsymmetricEncryptor : IAsymmetricPublicKey
+{
+ byte[] Encrypt(byte[] data);
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/Key/IAsymmetricKey.cs b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricKey.cs
new file mode 100644
index 0000000..0c44c22
--- /dev/null
+++ b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricKey.cs
@@ -0,0 +1,8 @@
+namespace DigitalData.Core.Abstractions.Security.Key;
+
+public interface IAsymmetricKey
+{
+ string? Id { get; }
+
+ string Content { get; }
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/Key/IAsymmetricPrivateKey.cs b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricPrivateKey.cs
new file mode 100644
index 0000000..14e4814
--- /dev/null
+++ b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricPrivateKey.cs
@@ -0,0 +1,8 @@
+namespace DigitalData.Core.Abstractions.Security.Key;
+
+public interface IAsymmetricPrivateKey : IAsymmetricKey
+{
+ bool IsEncrypted { get; }
+
+ IAsymmetricPublicKey PublicKey { get; }
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/Key/IAsymmetricPublicKey.cs b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricPublicKey.cs
new file mode 100644
index 0000000..2ca0e44
--- /dev/null
+++ b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricPublicKey.cs
@@ -0,0 +1,5 @@
+namespace DigitalData.Core.Abstractions.Security.Key;
+
+public interface IAsymmetricPublicKey : IAsymmetricKey
+{
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/Key/IAsymmetricTokenDescriptor.cs b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricTokenDescriptor.cs
new file mode 100644
index 0000000..5da7fc6
--- /dev/null
+++ b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricTokenDescriptor.cs
@@ -0,0 +1,74 @@
+using DigitalData.Core.Abstractions.Security.Common;
+using Microsoft.IdentityModel.Tokens;
+
+namespace DigitalData.Core.Abstractions.Security.Key;
+
+///
+/// Contains some information which used to create a security token. Designed to abstract
+///
+public interface IAsymmetricTokenDescriptor : IAsymmetricPrivateKey, IUniqueSecurityContext
+{
+ IAsymmetricTokenValidator Validator { get; }
+
+ TimeSpan Lifetime { get; init; }
+
+ #region SecurityTokenDescriptor Map
+ ///
+ /// Defines the compression algorithm that will be used to compress the JWT token payload.
+ ///
+ string CompressionAlgorithm { get; }
+
+ ///
+ /// Gets or sets the used to create a encrypted security token.
+ ///
+ EncryptingCredentials EncryptingCredentials { get; }
+
+ ///
+ /// Gets or sets the value of the 'expiration' claim. This value should be in UTC.
+ ///
+ DateTime? Expires { get; }
+
+ ///
+ /// Gets or sets the time the security token was issued. This value should be in UTC.
+ ///
+ DateTime? IssuedAt { get; }
+
+ ///
+ /// Gets or sets the notbefore time for the security token. This value should be in UTC.
+ ///
+ DateTime? NotBefore { get; }
+
+ ///
+ /// Gets or sets the token type.
+ /// If provided, this will be added as the value for the 'typ' header parameter. In the case of a JWE, this will be added to both the inner (JWS) and the outer token (JWE) header. By default, the value used is 'JWT'.
+ /// If also contains 'typ' header claim value, it will override the TokenType provided here.
+ /// This value is used only for JWT tokens and not for SAML/SAML2 tokens
+ ///
+ string TokenType { get; }
+
+ ///
+ /// Gets or sets the which contains any custom header claims that need to be added to the JWT token header.
+ /// The 'alg', 'kid', 'x5t', 'enc', and 'zip' claims are added by default based on the ,
+ /// , and/or provided and SHOULD NOT be included in this dictionary as this
+ /// will result in an exception being thrown.
+ /// These claims are only added to the outer header (in case of a JWE).
+ ///
+ IDictionary AdditionalHeaderClaims { get; }
+
+ ///
+ /// Gets or sets the which contains any custom header claims that need to be added to the inner JWT token header.
+ /// The 'alg', 'kid', 'x5t', 'enc', and 'zip' claims are added by default based on the ,
+ /// , and/or provided and SHOULD NOT be included in this dictionary as this
+ /// will result in an exception being thrown.
+ ///
+ /// For JsonWebTokenHandler, these claims are merged with while adding to the inner JWT header.
+ ///
+ ///
+ IDictionary AdditionalInnerHeaderClaims { get; }
+
+ ///
+ /// Gets or sets the used to create a security token.
+ ///
+ SigningCredentials SigningCredentials { get; }
+ #endregion SecurityTokenDescriptor
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/Key/IAsymmetricTokenValidator.cs b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricTokenValidator.cs
new file mode 100644
index 0000000..7c23cb6
--- /dev/null
+++ b/DigitalData.Core.Abstractions.Security/Key/IAsymmetricTokenValidator.cs
@@ -0,0 +1,8 @@
+using Microsoft.IdentityModel.Tokens;
+
+namespace DigitalData.Core.Abstractions.Security.Key;
+
+public interface IAsymmetricTokenValidator : IAsymmetricPublicKey
+{
+ SecurityKey SecurityKey { get; }
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/SecurityExtensions.cs b/DigitalData.Core.Abstractions.Security/SecurityExtensions.cs
deleted file mode 100644
index 08c0aaa..0000000
--- a/DigitalData.Core.Abstractions.Security/SecurityExtensions.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using Microsoft.IdentityModel.Tokens;
-using System.Text;
-
-namespace DigitalData.Core.Abstractions.Security
-{
- public static class SecurityExtensions
- {
- #region Unique Security Context
- public static IEnumerable GetByIssuer(this IEnumerable contextes, string issuer) where TUniqueSecurityContext: IUniqueSecurityContext
- => contextes.Where(c => c.Issuer == issuer);
-
- public static IEnumerable GetByAudience(this IEnumerable contextes, string audience) where TUniqueSecurityContext : IUniqueSecurityContext
- => contextes.Where(c => c.Audience == audience);
-
- public static TUniqueSecurityContext Get(this IEnumerable contextes, string issuer, string audience) where TUniqueSecurityContext : IUniqueSecurityContext
- => contextes.Where(c => c.Issuer == issuer && c.Audience == audience).SingleOrDefault()
- ?? throw new InvalidOperationException($"Exactly one {typeof(TUniqueSecurityContext).Name} must exist with Issuer: '{issuer}' and Audience: '{audience}'.");
-
- public static bool TryGet(this IEnumerable contextes, string issuer, string audience, out TUniqueSecurityContext context) where TUniqueSecurityContext : IUniqueSecurityContext
- {
-#pragma warning disable CS8601 // Possible null reference assignment.
- context = contextes.SingleOrDefault(c => c.Issuer == issuer && c.Audience == audience);
-#pragma warning restore CS8601 // Possible null reference assignment.
- return context is not null;
- }
-
- public static TUniqueSecurityContext Match(this IEnumerable contextes, IUniqueSecurityContext lookupContext) where TUniqueSecurityContext : IUniqueSecurityContext
- => contextes.Get(lookupContext.Issuer, lookupContext.Audience);
-
- public static bool TryMatch(this IEnumerable contextes, IUniqueSecurityContext lookupContext, out TUniqueSecurityContext context) where TUniqueSecurityContext : IUniqueSecurityContext
- => contextes.TryGet(lookupContext.Issuer, lookupContext.Audience, out context);
- #endregion Unique Security Context
-
- #region De/serilization
- internal static byte[] Base64ToByte(this string base64String) => Convert.FromBase64String(base64String);
-
- internal static string BytesToString(this byte[] bytes) => Encoding.UTF8.GetString(bytes);
-
- internal static string ToBase64String(this byte[] bytes) => Convert.ToBase64String(bytes);
-
- internal static byte[] ToBytes(this string str) => System.Text.Encoding.UTF8.GetBytes(str);
-
- public static string Decrypt(this IAsymmetricDecryptor decryptor, string data) => decryptor
- .Decrypt(data.Base64ToByte()).BytesToString();
- #endregion De/serilization
-
- #region Asymmetric Encryptor
- public static string Encrypt(this IAsymmetricEncryptor encryptor, string data) => encryptor.Encrypt(data.ToBytes()).ToBase64String();
- #endregion Asymmetric Encryptor
-
- #region Jwt Signature Handler
- public static string WriteToken(this IJwtSignatureHandler handler, SecurityTokenDescriptor descriptor)
- => handler.WriteToken(handler.CreateToken(descriptor));
-
- public static string WriteToken(this IJwtSignatureHandler handler, TPrincipal subject, IAsymmetricTokenDescriptor descriptor)
- => handler.WriteToken(handler.CreateToken(subject: subject, descriptor: descriptor));
-
- public static string WriteToken(this IJwtSignatureHandler handler, TPrincipal subject, string issuer, string audience)
- => handler.WriteToken(handler.CreateToken(subject: subject, issuer: issuer, audience: audience));
- #endregion Jwt Signature Handler
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Abstractions.Security/IAsymmetricKeyFactory.cs b/DigitalData.Core.Abstractions.Security/Services/IAsymmetricKeyFactory.cs
similarity index 87%
rename from DigitalData.Core.Abstractions.Security/IAsymmetricKeyFactory.cs
rename to DigitalData.Core.Abstractions.Security/Services/IAsymmetricKeyFactory.cs
index 31b8bdb..cf05fb0 100644
--- a/DigitalData.Core.Abstractions.Security/IAsymmetricKeyFactory.cs
+++ b/DigitalData.Core.Abstractions.Security/Services/IAsymmetricKeyFactory.cs
@@ -1,6 +1,7 @@
using System.Security.Cryptography;
+using DigitalData.Core.Abstractions.Security.Key;
-namespace DigitalData.Core.Abstractions.Security;
+namespace DigitalData.Core.Abstractions.Security.Services;
public interface IAsymmetricKeyFactory
{
diff --git a/DigitalData.Core.Abstractions.Security/IAsymmetricKeyPool.cs b/DigitalData.Core.Abstractions.Security/Services/IAsymmetricKeyPool.cs
similarity index 67%
rename from DigitalData.Core.Abstractions.Security/IAsymmetricKeyPool.cs
rename to DigitalData.Core.Abstractions.Security/Services/IAsymmetricKeyPool.cs
index ffc9da3..beddace 100644
--- a/DigitalData.Core.Abstractions.Security/IAsymmetricKeyPool.cs
+++ b/DigitalData.Core.Abstractions.Security/Services/IAsymmetricKeyPool.cs
@@ -1,4 +1,6 @@
-namespace DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
+
+namespace DigitalData.Core.Abstractions.Security.Services;
public interface IAsymmetricKeyPool : IAsymmetricKeyFactory
{
diff --git a/DigitalData.Core.Abstractions.Security/IJwtSignatureHandler.cs b/DigitalData.Core.Abstractions.Security/Services/IJwtSignatureHandler.cs
similarity index 71%
rename from DigitalData.Core.Abstractions.Security/IJwtSignatureHandler.cs
rename to DigitalData.Core.Abstractions.Security/Services/IJwtSignatureHandler.cs
index 574ffc2..473d5de 100644
--- a/DigitalData.Core.Abstractions.Security/IJwtSignatureHandler.cs
+++ b/DigitalData.Core.Abstractions.Security/Services/IJwtSignatureHandler.cs
@@ -1,6 +1,7 @@
-using Microsoft.IdentityModel.Tokens;
+using DigitalData.Core.Abstractions.Security.Key;
+using Microsoft.IdentityModel.Tokens;
-namespace DigitalData.Core.Abstractions.Security
+namespace DigitalData.Core.Abstractions.Security.Services
{
public interface IJwtSignatureHandler
{
diff --git a/DigitalData.Core.Security/Config/ClaimDescriptor.cs b/DigitalData.Core.Security/Config/ClaimDescriptor.cs
index f82a36e..12e5b08 100644
--- a/DigitalData.Core.Security/Config/ClaimDescriptor.cs
+++ b/DigitalData.Core.Security/Config/ClaimDescriptor.cs
@@ -1,11 +1,10 @@
using System.Security.Claims;
-namespace DigitalData.Core.Security.Config
-{
- public class ClaimDescriptor
- {
- public Func>? CreateClaims { get; init; }
+namespace DigitalData.Core.Security.Config;
- public Func? CreateSubject { get; init; }
- }
+public class ClaimDescriptor
+{
+ public Func>? CreateClaims { get; init; }
+
+ public Func? CreateSubject { get; init; }
}
\ No newline at end of file
diff --git a/DigitalData.Core.Security/Config/MappingProfile.cs b/DigitalData.Core.Security/Config/MappingProfile.cs
index 1bbbf6d..e5816aa 100644
--- a/DigitalData.Core.Security/Config/MappingProfile.cs
+++ b/DigitalData.Core.Security/Config/MappingProfile.cs
@@ -1,14 +1,13 @@
using AutoMapper;
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
using Microsoft.IdentityModel.Tokens;
-namespace DigitalData.Core.Security.Config
+namespace DigitalData.Core.Security.Config;
+
+public class MappingProfile : Profile
{
- public class MappingProfile : Profile
+ public MappingProfile()
{
- public MappingProfile()
- {
- CreateMap();
- }
+ CreateMap();
}
}
\ No newline at end of file
diff --git a/DigitalData.Core.Security/DIExtensions.cs b/DigitalData.Core.Security/DIExtensions.cs
deleted file mode 100644
index d6b6b7b..0000000
--- a/DigitalData.Core.Security/DIExtensions.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using DigitalData.Core.Abstractions.Security;
-using DigitalData.Core.Security.Config;
-using DigitalData.Core.Security.Services;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
-using System.Security.Claims;
-
-namespace DigitalData.Core.Security
-{
- public static class DIExtensions
- {
- ///
- /// Registers a custom asym crypt service with specified parameters from the given configuration section.
- ///
- ///
- ///
- /// The updated with the RSA Factory registered.
- public static IServiceCollection AddCryptoFactory(this IServiceCollection services, IConfiguration configuration) => services
- .Configure(configuration)
- .AddAutoMapper(typeof(MappingProfile).Assembly)
- .AddSingleton()
- .AddSingleton()
- .AddHostedService();
-
- public static IServiceCollection AddJwtSignatureHandler(this IServiceCollection services,
- Func>? claimsMapper = null,
- Func? subjectMapper = null)
- => services
- .AddSingleton, JwtSignatureHandler>()
- .AddSingleton(sp => Options.Create(new ClaimDescriptor
- {
- CreateClaims = claimsMapper,
- CreateSubject = subjectMapper
- }));
- }
-}
\ No newline at end of file
diff --git a/DigitalData.Core.Security/DigitalData.Core.Security.csproj b/DigitalData.Core.Security/DigitalData.Core.Security.csproj
index 9b1e365..7309f99 100644
--- a/DigitalData.Core.Security/DigitalData.Core.Security.csproj
+++ b/DigitalData.Core.Security/DigitalData.Core.Security.csproj
@@ -34,7 +34,6 @@
-
diff --git a/DigitalData.Core.Security/Extension.cs b/DigitalData.Core.Security/Extension.cs
deleted file mode 100644
index f767b74..0000000
--- a/DigitalData.Core.Security/Extension.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using AutoMapper;
-using DigitalData.Core.Abstractions.Security;
-using Microsoft.IdentityModel.Tokens;
-
-namespace DigitalData.Core.Security
-{
- internal static class Extension
- {
- ///
- /// Converts a to a formatted string based on the specified format string.
- ///
- /// - If the format contains the symbol “//”, the method divides the numeric value obtained from the left side of the format
- /// by one minus the numeric value obtained from the right side of the format string and adds one. For instance:
- ///
- /// - If the date is 02.03.2024 and the format is "MM//2", it extracts the month (02), subtracts one (3), divides it by 2,
- /// rounds down the outgoing number (1), adds one to the number (resulting in 2).
- ///
- /// - If the format does not contain "//", the method uses the default format.
- ///
- ///
- /// The value to be formatted.
- /// The format string that dictates the formatting of the date. If the format includes the "//" symbol,
- /// it splits the string at "//" and divides the left-side value by the right-side value. The format string can include standard
- /// format patterns.
- /// A string representation of the formatted date, or the result of the division operation if "//" is present in the format.
- /// Thrown if the format string is invalid, such as having an incorrect number of parts after "//".
- /// Thrown if the right side of the "//" contains a zero, resulting in division by zero.
- /// Thrown if either the left-side or right-side value of "//" cannot be parsed as an integer.
- internal static string ToTag(this DateTime date, string format)
- {
- if (format is not null && format.Contains("//"))
- {
- var subStrings = format.Split("//");
-
- if (subStrings.Length != 2)
- throw new ArgumentException($"Date tag format {format} is invalid. It must contain exactly one '//' separator.", nameof(format));
-
- var formattedLeft = date.ToString(subStrings[0]);
-
- if (!int.TryParse(formattedLeft, out var dateValue))
- throw new FormatException($"The left-side value ({formattedLeft}) of the format could not be parsed to an integer.");
-
- if (!int.TryParse(subStrings[1], out var divisor))
- throw new FormatException($"The right-side value ({divisor}) of the format could not be parsed to an integer.");
-
- if (divisor == 0)
- throw new DivideByZeroException($"Date tag format {format} includes division by zero, which is not allowed.");
-
- var result = (dateValue - 1) / divisor + 1;
- return result.ToString();
- }
-
- return date.ToString(format);
- }
-
- ///
- /// Converts a to a formatted string based on the specified format string.
- ///
- /// - If the format contains the symbol “//”, the method divides the numeric value obtained from the left side of the format
- /// by one minus the numeric value obtained from the right side of the format string and adds one. For instance:
- ///
- /// - If the date is 02.03.2024 and the format is "MM//2", it extracts the month (02), subtracts one (3), divides it by 2,
- /// rounds down the outgoing number (1), adds one to the number (resulting in 2).
- ///
- /// - If the format does not contain "//", the method uses the default format.
- ///
- /// This method provides a way to format the date based on typical or customized rules, including mathematical operations like division.
- ///
- /// The value to be formatted. It will convert to DateTime to use the method shared with DateTime.
- /// The format string that dictates the formatting of the date. If the format includes the "//" symbol,
- /// it splits the string at "//" and divides the left-side value by the right-side value. The format string can include standard
- /// format patterns.
- /// A string representation of the formatted date, or the result of the division operation if "//" is present in the format.
- /// Thrown if the format string is invalid, such as having an incorrect number of parts after "//".
- /// Thrown if the right side of the "//" contains a zero, resulting in division by zero.
- /// Thrown if either the left-side or right-side value of "//" cannot be parsed as an integer.
- internal static string ToTag(this DateOnly date, string format) => date.ToDateTime(new()).ToTag(format);
-
- ///
- /// Maps a to a .
- ///
- /// The instance used for mapping.
- /// The instance to be mapped.
- /// A instance populated with the mapped values.
- /// Thrown if or is null.
- 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/Extensions/DIExtensions.cs b/DigitalData.Core.Security/Extensions/DIExtensions.cs
new file mode 100644
index 0000000..8b6d4b4
--- /dev/null
+++ b/DigitalData.Core.Security/Extensions/DIExtensions.cs
@@ -0,0 +1,36 @@
+using DigitalData.Core.Abstractions.Security.Services;
+using DigitalData.Core.Security.Config;
+using DigitalData.Core.Security.Services;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using System.Security.Claims;
+
+namespace DigitalData.Core.Security.Extensions;
+
+public static class DIExtensions
+{
+ ///
+ /// Registers a custom asym crypt service with specified parameters from the given configuration section.
+ ///
+ ///
+ ///
+ /// The updated with the RSA Factory registered.
+ public static IServiceCollection AddCryptoFactory(this IServiceCollection services, IConfiguration configuration) => services
+ .Configure(configuration)
+ .AddAutoMapper(typeof(MappingProfile).Assembly)
+ .AddSingleton()
+ .AddSingleton()
+ .AddHostedService();
+
+ public static IServiceCollection AddJwtSignatureHandler(this IServiceCollection services,
+ Func>? claimsMapper = null,
+ Func? subjectMapper = null)
+ => services
+ .AddSingleton, JwtSignatureHandler>()
+ .AddSingleton(sp => Options.Create(new ClaimDescriptor
+ {
+ CreateClaims = claimsMapper,
+ CreateSubject = subjectMapper
+ }));
+}
\ No newline at end of file
diff --git a/DigitalData.Core.Security/Extensions/Extension.cs b/DigitalData.Core.Security/Extensions/Extension.cs
new file mode 100644
index 0000000..ec19e5d
--- /dev/null
+++ b/DigitalData.Core.Security/Extensions/Extension.cs
@@ -0,0 +1,88 @@
+using AutoMapper;
+using DigitalData.Core.Abstractions.Security.Key;
+using Microsoft.IdentityModel.Tokens;
+
+namespace DigitalData.Core.Security.Extensions;
+
+internal static class Extension
+{
+ ///
+ /// Converts a to a formatted string based on the specified format string.
+ ///
+ /// - If the format contains the symbol “//”, the method divides the numeric value obtained from the left side of the format
+ /// by one minus the numeric value obtained from the right side of the format string and adds one. For instance:
+ ///
+ /// - If the date is 02.03.2024 and the format is "MM//2", it extracts the month (02), subtracts one (3), divides it by 2,
+ /// rounds down the outgoing number (1), adds one to the number (resulting in 2).
+ ///
+ /// - If the format does not contain "//", the method uses the default format.
+ ///
+ ///
+ /// The value to be formatted.
+ /// The format string that dictates the formatting of the date. If the format includes the "//" symbol,
+ /// it splits the string at "//" and divides the left-side value by the right-side value. The format string can include standard
+ /// format patterns.
+ /// A string representation of the formatted date, or the result of the division operation if "//" is present in the format.
+ /// Thrown if the format string is invalid, such as having an incorrect number of parts after "//".
+ /// Thrown if the right side of the "//" contains a zero, resulting in division by zero.
+ /// Thrown if either the left-side or right-side value of "//" cannot be parsed as an integer.
+ internal static string ToTag(this DateTime date, string format)
+ {
+ if (format is not null && format.Contains("//"))
+ {
+ var subStrings = format.Split("//");
+
+ if (subStrings.Length != 2)
+ throw new ArgumentException($"Date tag format {format} is invalid. It must contain exactly one '//' separator.", nameof(format));
+
+ var formattedLeft = date.ToString(subStrings[0]);
+
+ if (!int.TryParse(formattedLeft, out var dateValue))
+ throw new FormatException($"The left-side value ({formattedLeft}) of the format could not be parsed to an integer.");
+
+ if (!int.TryParse(subStrings[1], out var divisor))
+ throw new FormatException($"The right-side value ({divisor}) of the format could not be parsed to an integer.");
+
+ if (divisor == 0)
+ throw new DivideByZeroException($"Date tag format {format} includes division by zero, which is not allowed.");
+
+ var result = (dateValue - 1) / divisor + 1;
+ return result.ToString();
+ }
+
+ return date.ToString(format);
+ }
+
+ ///
+ /// Converts a to a formatted string based on the specified format string.
+ ///
+ /// - If the format contains the symbol “//”, the method divides the numeric value obtained from the left side of the format
+ /// by one minus the numeric value obtained from the right side of the format string and adds one. For instance:
+ ///
+ /// - If the date is 02.03.2024 and the format is "MM//2", it extracts the month (02), subtracts one (3), divides it by 2,
+ /// rounds down the outgoing number (1), adds one to the number (resulting in 2).
+ ///
+ /// - If the format does not contain "//", the method uses the default format.
+ ///
+ /// This method provides a way to format the date based on typical or customized rules, including mathematical operations like division.
+ ///
+ /// The value to be formatted. It will convert to DateTime to use the method shared with DateTime.
+ /// The format string that dictates the formatting of the date. If the format includes the "//" symbol,
+ /// it splits the string at "//" and divides the left-side value by the right-side value. The format string can include standard
+ /// format patterns.
+ /// A string representation of the formatted date, or the result of the division operation if "//" is present in the format.
+ /// Thrown if the format string is invalid, such as having an incorrect number of parts after "//".
+ /// Thrown if the right side of the "//" contains a zero, resulting in division by zero.
+ /// Thrown if either the left-side or right-side value of "//" cannot be parsed as an integer.
+ internal static string ToTag(this DateOnly date, string format) => date.ToDateTime(new()).ToTag(format);
+
+ ///
+ /// Maps a to a .
+ ///
+ /// The instance used for mapping.
+ /// The instance to be mapped.
+ /// A instance populated with the mapped values.
+ /// Thrown if or is null.
+ 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/Auth/RSATokenDescriptor.cs b/DigitalData.Core.Security/RSAKey/Auth/RSATokenDescriptor.cs
index 9e4c02e..ecd849c 100644
--- a/DigitalData.Core.Security/RSAKey/Auth/RSATokenDescriptor.cs
+++ b/DigitalData.Core.Security/RSAKey/Auth/RSATokenDescriptor.cs
@@ -1,4 +1,4 @@
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
using DigitalData.Core.Security.RSAKey.Base;
using Microsoft.IdentityModel.Tokens;
diff --git a/DigitalData.Core.Security/RSAKey/Auth/RSATokenValidator.cs b/DigitalData.Core.Security/RSAKey/Auth/RSATokenValidator.cs
index cdf9471..1260eff 100644
--- a/DigitalData.Core.Security/RSAKey/Auth/RSATokenValidator.cs
+++ b/DigitalData.Core.Security/RSAKey/Auth/RSATokenValidator.cs
@@ -1,4 +1,4 @@
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
using DigitalData.Core.Security.RSAKey.Base;
using Microsoft.IdentityModel.Tokens;
diff --git a/DigitalData.Core.Security/RSAKey/Base/RSAKeyBase.cs b/DigitalData.Core.Security/RSAKey/Base/RSAKeyBase.cs
index a3c0472..0fae884 100644
--- a/DigitalData.Core.Security/RSAKey/Base/RSAKeyBase.cs
+++ b/DigitalData.Core.Security/RSAKey/Base/RSAKeyBase.cs
@@ -1,4 +1,4 @@
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
using System.Security.Cryptography;
namespace DigitalData.Core.Security.RSAKey.Base;
diff --git a/DigitalData.Core.Security/RSAKey/Base/RSAPrivateKey.cs b/DigitalData.Core.Security/RSAKey/Base/RSAPrivateKey.cs
index 6305d03..082080b 100644
--- a/DigitalData.Core.Security/RSAKey/Base/RSAPrivateKey.cs
+++ b/DigitalData.Core.Security/RSAKey/Base/RSAPrivateKey.cs
@@ -1,4 +1,4 @@
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
using System.Security.Cryptography;
namespace DigitalData.Core.Security.RSAKey.Base;
diff --git a/DigitalData.Core.Security/RSAKey/Base/RSAPublicKey.cs b/DigitalData.Core.Security/RSAKey/Base/RSAPublicKey.cs
index 50329b8..f208485 100644
--- a/DigitalData.Core.Security/RSAKey/Base/RSAPublicKey.cs
+++ b/DigitalData.Core.Security/RSAKey/Base/RSAPublicKey.cs
@@ -1,4 +1,4 @@
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
namespace DigitalData.Core.Security.RSAKey.Base;
diff --git a/DigitalData.Core.Security/RSAKey/Crypto/RSADecryptor.cs b/DigitalData.Core.Security/RSAKey/Crypto/RSADecryptor.cs
index 4fea226..ae6ee32 100644
--- a/DigitalData.Core.Security/RSAKey/Crypto/RSADecryptor.cs
+++ b/DigitalData.Core.Security/RSAKey/Crypto/RSADecryptor.cs
@@ -1,4 +1,4 @@
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
using DigitalData.Core.Security.RSAKey.Base;
using System.Reflection;
using System.Security.Cryptography;
diff --git a/DigitalData.Core.Security/RSAKey/Crypto/RSAEncryptor.cs b/DigitalData.Core.Security/RSAKey/Crypto/RSAEncryptor.cs
index c9b0d43..e1f1db8 100644
--- a/DigitalData.Core.Security/RSAKey/Crypto/RSAEncryptor.cs
+++ b/DigitalData.Core.Security/RSAKey/Crypto/RSAEncryptor.cs
@@ -1,4 +1,4 @@
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
using DigitalData.Core.Security.RSAKey.Base;
using System.Reflection;
using System.Security.Cryptography;
diff --git a/DigitalData.Core.Security/Secrets.cs b/DigitalData.Core.Security/Secrets.cs
index 9774ec1..064c825 100644
--- a/DigitalData.Core.Security/Secrets.cs
+++ b/DigitalData.Core.Security/Secrets.cs
@@ -1,14 +1,13 @@
using System.Text.Json.Serialization;
-namespace DigitalData.Core.Security
+namespace DigitalData.Core.Security;
+
+public static class Secrets
{
- public static class Secrets
- {
- public static readonly DateTime CreationDate = new (2024, 11, 19);
+ public static readonly DateTime CreationDate = new (2024, 11, 19);
- public static readonly Version Version = new (1, 0);
+ public static readonly Version Version = new (1, 0);
- [JsonIgnore]
- internal static readonly string PBE_PASSWORD = "9mk@i/$QY&Mw@_--dI^ahlXpNKEtv_U-,V-46b19_-Z6-U_*89_n1_-5-r-_+_$_IY_mYQl-";
- }
+ [JsonIgnore]
+ internal static readonly string PBE_PASSWORD = "9mk@i/$QY&Mw@_--dI^ahlXpNKEtv_U-,V-46b19_-Z6-U_*89_n1_-5-r-_+_$_IY_mYQl-";
}
\ No newline at end of file
diff --git a/DigitalData.Core.Security/Services/JwtSignatureHandler.cs b/DigitalData.Core.Security/Services/JwtSignatureHandler.cs
index 71c0a17..4b3ee18 100644
--- a/DigitalData.Core.Security/Services/JwtSignatureHandler.cs
+++ b/DigitalData.Core.Security/Services/JwtSignatureHandler.cs
@@ -1,6 +1,9 @@
using AutoMapper;
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Extensions;
+using DigitalData.Core.Abstractions.Security.Key;
+using DigitalData.Core.Abstractions.Security.Services;
using DigitalData.Core.Security.Config;
+using DigitalData.Core.Security.Extensions;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
diff --git a/DigitalData.Core.Security/Services/PemFileInitalizer.cs b/DigitalData.Core.Security/Services/PemFileInitalizer.cs
index 6dc6ae4..6193f97 100644
--- a/DigitalData.Core.Security/Services/PemFileInitalizer.cs
+++ b/DigitalData.Core.Security/Services/PemFileInitalizer.cs
@@ -1,4 +1,5 @@
using DigitalData.Core.Security.Config;
+using DigitalData.Core.Security.Extensions;
using DigitalData.Core.Security.RSAKey.Auth;
using DigitalData.Core.Security.RSAKey.Base;
using Microsoft.Extensions.Hosting;
diff --git a/DigitalData.Core.Security/Services/RSAFactory.cs b/DigitalData.Core.Security/Services/RSAFactory.cs
index 63b3566..9d8899a 100644
--- a/DigitalData.Core.Security/Services/RSAFactory.cs
+++ b/DigitalData.Core.Security/Services/RSAFactory.cs
@@ -1,4 +1,5 @@
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
+using DigitalData.Core.Abstractions.Security.Services;
using DigitalData.Core.Security.Config;
using DigitalData.Core.Security.RSAKey.Crypto;
using System.Security.Cryptography;
diff --git a/DigitalData.Core.Security/Services/RSAPool.cs b/DigitalData.Core.Security/Services/RSAPool.cs
index 2dcf74c..bd209c3 100644
--- a/DigitalData.Core.Security/Services/RSAPool.cs
+++ b/DigitalData.Core.Security/Services/RSAPool.cs
@@ -1,4 +1,5 @@
-using DigitalData.Core.Abstractions.Security;
+using DigitalData.Core.Abstractions.Security.Key;
+using DigitalData.Core.Abstractions.Security.Services;
using DigitalData.Core.Security.Config;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;