feat(RSAKey): Unterverzeichnisse auth, base und crypto erstellt und zugehörige RSA-Klassen verschoben
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using DigitalData.Core.Security.RSAKey;
|
||||
using DigitalData.Core.Security.RSAKey.Auth;
|
||||
using DigitalData.Core.Security.RSAKey.Crypto;
|
||||
|
||||
namespace DigitalData.Core.Security.Config
|
||||
{
|
||||
|
||||
119
DigitalData.Core.Security/RSAKey/Auth/RSATokenDescriptor.cs
Normal file
119
DigitalData.Core.Security/RSAKey/Auth/RSATokenDescriptor.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.RSAKey.Base;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey.Auth;
|
||||
|
||||
/// <summary>
|
||||
/// Contains some information which used to create a security token. Designed to abstract <see cref="SecurityTokenDescriptor"/>
|
||||
/// </summary>
|
||||
public class RSATokenDescriptor : RSAPrivateKey, IAsymmetricTokenDescriptor
|
||||
{
|
||||
private readonly Lazy<RSATokenValidator> _lazyTokenValidator;
|
||||
|
||||
public IAsymmetricTokenValidator Validator => _lazyTokenValidator.Value;
|
||||
|
||||
public required TimeSpan Lifetime { get; init; }
|
||||
|
||||
#region SecurityTokenDescriptor Map
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the 'audience' claim.
|
||||
/// </summary>
|
||||
public required string Audience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the compression algorithm that will be used to compress the JWT token payload.
|
||||
/// </summary>
|
||||
public string CompressionAlgorithm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="EncryptingCredentials"/> used to create a encrypted security token.
|
||||
/// </summary>
|
||||
public EncryptingCredentials EncryptingCredentials { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the 'expiration' claim. This value should be in UTC.
|
||||
/// The expiration time is the sum of DateTime.Now and LifeTime.
|
||||
/// </summary>
|
||||
public DateTime? Expires => DateTime.Now.AddTicks(Lifetime.Ticks);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the issuer of this <see cref="SecurityTokenDescriptor"/>.
|
||||
/// </summary>
|
||||
public required string Issuer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the time the security token was issued. This value should be in UTC.
|
||||
/// </summary>
|
||||
public DateTime? IssuedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the notbefore time for the security token. This value should be in UTC.
|
||||
/// </summary>
|
||||
public DateTime? NotBefore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the token type.
|
||||
/// <remarks> 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 <see cref="AdditionalHeaderClaims"/> 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</remarks>
|
||||
/// </summary>
|
||||
public string TokenType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Dictionary{TKey, TValue}"/> 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 <see cref="SigningCredentials"/>,
|
||||
/// <see cref="EncryptingCredentials"/>, and/or <see cref="CompressionAlgorithm"/> provided and SHOULD NOT be included in this dictionary as this
|
||||
/// will result in an exception being thrown.
|
||||
/// <remarks> These claims are only added to the outer header (in case of a JWE).</remarks>
|
||||
/// </summary>
|
||||
public IDictionary<string, object> AdditionalHeaderClaims { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Dictionary{TKey, TValue}"/> 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 <see cref="SigningCredentials"/>,
|
||||
/// <see cref="EncryptingCredentials"/>, and/or <see cref="CompressionAlgorithm"/> provided and SHOULD NOT be included in this dictionary as this
|
||||
/// will result in an exception being thrown.
|
||||
/// <remarks>
|
||||
/// For JsonWebTokenHandler, these claims are merged with <see cref="AdditionalHeaderClaims"/> while adding to the inner JWT header.
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
public IDictionary<string, object> AdditionalInnerHeaderClaims { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="SigningCredentials"/> used to create a security token.
|
||||
/// </summary>
|
||||
public SigningCredentials SigningCredentials => _lazySigningCredentials.Value;
|
||||
#endregion SecurityTokenDescriptor
|
||||
|
||||
private readonly Lazy<RsaSecurityKey> _lazyRsaSecurityKey;
|
||||
|
||||
public SecurityKey SecurityKey => _lazyRsaSecurityKey.Value;
|
||||
|
||||
private readonly Lazy<SigningCredentials> _lazySigningCredentials;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the signature algorithm to be applied to the <see cref="SigningCredentials"/>.
|
||||
/// Default is <see cref="SecurityAlgorithms.RsaSha256"/>.
|
||||
/// </summary>
|
||||
public string SigningAlgorithm { get; init; } = SecurityAlgorithms.RsaSha256;
|
||||
|
||||
/// <summary>
|
||||
/// Optionally specifies the digest algorithm to be applied during the signing process for the <see cref="SigningCredentials"/>.
|
||||
/// If not provided, the default algorithm is used.
|
||||
/// </summary>
|
||||
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.
|
||||
{
|
||||
_lazyTokenValidator = new(CreatePublicKey<RSATokenValidator>);
|
||||
|
||||
_lazyRsaSecurityKey = new(() => new RsaSecurityKey(RSA));
|
||||
|
||||
_lazySigningCredentials = new(() => SigningDigest is null
|
||||
? new(SecurityKey, SigningAlgorithm)
|
||||
: new(SecurityKey, SigningAlgorithm, SigningDigest));
|
||||
}
|
||||
}
|
||||
17
DigitalData.Core.Security/RSAKey/Auth/RSATokenValidator.cs
Normal file
17
DigitalData.Core.Security/RSAKey/Auth/RSATokenValidator.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.RSAKey.Base;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey.Auth;
|
||||
|
||||
public class RSATokenValidator : RSAPublicKey, IAsymmetricTokenValidator
|
||||
{
|
||||
private readonly Lazy<RsaSecurityKey> _lazyRsaSecurityKey;
|
||||
|
||||
public SecurityKey SecurityKey => _lazyRsaSecurityKey.Value;
|
||||
|
||||
public RSATokenValidator()
|
||||
{
|
||||
_lazyRsaSecurityKey = new(() => new RsaSecurityKey(RSA));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey
|
||||
namespace DigitalData.Core.Security.RSAKey.Base;
|
||||
|
||||
public class RSAKeyBase : IAsymmetricKey
|
||||
{
|
||||
public class RSAKeyBase : IAsymmetricKey
|
||||
{
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public virtual string Content { get; init; }
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
@@ -12,5 +12,4 @@ namespace DigitalData.Core.Security.RSAKey
|
||||
public string? Id { get; init; }
|
||||
|
||||
protected virtual RSA RSA { get; } = RSA.Create();
|
||||
}
|
||||
}
|
||||
54
DigitalData.Core.Security/RSAKey/Base/RSAPrivateKey.cs
Normal file
54
DigitalData.Core.Security/RSAKey/Base/RSAPrivateKey.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey.Base;
|
||||
|
||||
public class RSAPrivateKey : RSAKeyBase, IAsymmetricPrivateKey, IAsymmetricKey
|
||||
{
|
||||
private string? _pem;
|
||||
|
||||
public override string Content
|
||||
{
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
get => _pem;
|
||||
#pragma warning restore CS8603 // Possible null reference return.
|
||||
init
|
||||
{
|
||||
_pem = value;
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPemNull => _pem is null;
|
||||
|
||||
public bool IsEncrypted { get; init; }
|
||||
|
||||
protected TPublicKey CreatePublicKey<TPublicKey>() where TPublicKey : RSAPublicKey, new()
|
||||
=> new() { Content = RSA.ExportRSAPublicKeyPem() };
|
||||
|
||||
private readonly Lazy<RSAPublicKey> _lazyPublicKey;
|
||||
|
||||
public IAsymmetricPublicKey PublicKey => _lazyPublicKey.Value;
|
||||
|
||||
public RSAPrivateKey()
|
||||
{
|
||||
_lazyPublicKey = new(CreatePublicKey<RSAPublicKey>);
|
||||
}
|
||||
|
||||
internal void SetPem(string pem)
|
||||
{
|
||||
_pem = pem;
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_pem))
|
||||
throw new InvalidOperationException($"The content of RSA private key is null or empty. Id: {Id}.");
|
||||
|
||||
if (IsEncrypted)
|
||||
RSA.ImportFromEncryptedPem(Content, Secrets.PBE_PASSWORD.AsSpan());
|
||||
else
|
||||
RSA.ImportFromPem(Content);
|
||||
}
|
||||
}
|
||||
16
DigitalData.Core.Security/RSAKey/Base/RSAPublicKey.cs
Normal file
16
DigitalData.Core.Security/RSAKey/Base/RSAPublicKey.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey.Base;
|
||||
|
||||
public class RSAPublicKey : RSAKeyBase, IAsymmetricPublicKey, IAsymmetricKey
|
||||
{
|
||||
public override string Content
|
||||
{
|
||||
get => base.Content;
|
||||
init
|
||||
{
|
||||
base.Content = value;
|
||||
RSA.ImportFromPem(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
33
DigitalData.Core.Security/RSAKey/Crypto/RSADecryptor.cs
Normal file
33
DigitalData.Core.Security/RSAKey/Crypto/RSADecryptor.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.RSAKey.Base;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey.Crypto;
|
||||
|
||||
public class RSADecryptor : RSAPrivateKey, IAsymmetricDecryptor
|
||||
{
|
||||
public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256;
|
||||
|
||||
// TODO: add as json converter to IConfigurIConfiguration.Config
|
||||
public string PaddingName
|
||||
{
|
||||
get => Padding.ToString();
|
||||
init => Padding = typeof(RSAEncryptionPadding).GetProperty(value, BindingFlags.Public | BindingFlags.Static)?.GetValue(null) as RSAEncryptionPadding ?? throw new ArgumentException($"Padding '{value}' not found.");
|
||||
}
|
||||
|
||||
public byte[] Decrypt(byte[] data) => RSA.Decrypt(data, Padding);
|
||||
|
||||
private readonly Lazy<IAsymmetricEncryptor> _lazyEncryptor;
|
||||
|
||||
public IAsymmetricEncryptor Encryptor => _lazyEncryptor.Value;
|
||||
|
||||
public RSADecryptor()
|
||||
{
|
||||
_lazyEncryptor = new(() => new RSAEncryptor()
|
||||
{
|
||||
Content = RSA.ExportRSAPublicKeyPem(),
|
||||
Padding = Padding
|
||||
});
|
||||
}
|
||||
}
|
||||
20
DigitalData.Core.Security/RSAKey/Crypto/RSAEncryptor.cs
Normal file
20
DigitalData.Core.Security/RSAKey/Crypto/RSAEncryptor.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.RSAKey.Base;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey.Crypto;
|
||||
|
||||
public class RSAEncryptor : RSAPublicKey, IAsymmetricEncryptor
|
||||
{
|
||||
public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256;
|
||||
|
||||
// TODO: add as json converter to IConfigurIConfiguration.Config
|
||||
public string PaddingName
|
||||
{
|
||||
get => Padding.ToString();
|
||||
init => Padding = typeof(RSAEncryptionPadding).GetProperty(value, BindingFlags.Public | BindingFlags.Static)?.GetValue(null) as RSAEncryptionPadding ?? throw new ArgumentException($"Padding '{value}' not found.");
|
||||
}
|
||||
|
||||
public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey
|
||||
{
|
||||
public class RSADecryptor : RSAPrivateKey, IAsymmetricDecryptor
|
||||
{
|
||||
public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256;
|
||||
|
||||
// TODO: add as json converter to IConfigurIConfiguration.Config
|
||||
public string PaddingName
|
||||
{
|
||||
get => Padding.ToString();
|
||||
init => Padding = typeof(RSAEncryptionPadding).GetProperty(value, BindingFlags.Public | BindingFlags.Static)?.GetValue(null) as RSAEncryptionPadding ?? throw new ArgumentException($"Padding '{value}' not found.");
|
||||
}
|
||||
|
||||
public byte[] Decrypt(byte[] data) => RSA.Decrypt(data, Padding);
|
||||
|
||||
private readonly Lazy<IAsymmetricEncryptor> _lazyEncryptor;
|
||||
|
||||
public IAsymmetricEncryptor Encryptor => _lazyEncryptor.Value;
|
||||
|
||||
public RSADecryptor()
|
||||
{
|
||||
_lazyEncryptor = new(() => new RSAEncryptor()
|
||||
{
|
||||
Content = RSA.ExportRSAPublicKeyPem(),
|
||||
Padding = Padding
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey
|
||||
{
|
||||
public class RSAEncryptor : RSAPublicKey, IAsymmetricEncryptor
|
||||
{
|
||||
public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256;
|
||||
|
||||
// TODO: add as json converter to IConfigurIConfiguration.Config
|
||||
public string PaddingName
|
||||
{
|
||||
get => Padding.ToString();
|
||||
init => Padding = typeof(RSAEncryptionPadding).GetProperty(value, BindingFlags.Public | BindingFlags.Static)?.GetValue(null) as RSAEncryptionPadding ?? throw new ArgumentException($"Padding '{value}' not found.");
|
||||
}
|
||||
|
||||
public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey
|
||||
{
|
||||
public class RSAPrivateKey : RSAKeyBase, IAsymmetricPrivateKey, IAsymmetricKey
|
||||
{
|
||||
private string? _pem;
|
||||
|
||||
public override string Content
|
||||
{
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
get => _pem;
|
||||
#pragma warning restore CS8603 // Possible null reference return.
|
||||
init
|
||||
{
|
||||
_pem = value;
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPemNull => _pem is null;
|
||||
|
||||
public bool IsEncrypted { get; init; }
|
||||
|
||||
protected TPublicKey CreatePublicKey<TPublicKey>() where TPublicKey : RSAPublicKey, new()
|
||||
=> new() { Content = RSA.ExportRSAPublicKeyPem() };
|
||||
|
||||
private readonly Lazy<RSAPublicKey> _lazyPublicKey;
|
||||
|
||||
public IAsymmetricPublicKey PublicKey => _lazyPublicKey.Value;
|
||||
|
||||
public RSAPrivateKey()
|
||||
{
|
||||
_lazyPublicKey = new(CreatePublicKey<RSAPublicKey>);
|
||||
}
|
||||
|
||||
internal void SetPem(string pem)
|
||||
{
|
||||
_pem = pem;
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_pem))
|
||||
throw new InvalidOperationException ($"The content of RSA private key is null or empty. Id: {Id}.");
|
||||
|
||||
if (IsEncrypted)
|
||||
RSA.ImportFromEncryptedPem(Content, Secrets.PBE_PASSWORD.AsSpan());
|
||||
else
|
||||
RSA.ImportFromPem(Content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey
|
||||
{
|
||||
public class RSAPublicKey : RSAKeyBase, IAsymmetricPublicKey, IAsymmetricKey
|
||||
{
|
||||
public override string Content
|
||||
{
|
||||
get => base.Content;
|
||||
init
|
||||
{
|
||||
base.Content = value;
|
||||
RSA.ImportFromPem(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains some information which used to create a security token. Designed to abstract <see cref="SecurityTokenDescriptor"/>
|
||||
/// </summary>
|
||||
public class RSATokenDescriptor : RSAPrivateKey, IAsymmetricTokenDescriptor
|
||||
{
|
||||
private readonly Lazy<RSATokenValidator> _lazyTokenValidator;
|
||||
|
||||
public IAsymmetricTokenValidator Validator => _lazyTokenValidator.Value;
|
||||
|
||||
public required TimeSpan Lifetime { get; init; }
|
||||
|
||||
#region SecurityTokenDescriptor Map
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the 'audience' claim.
|
||||
/// </summary>
|
||||
public required string Audience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the compression algorithm that will be used to compress the JWT token payload.
|
||||
/// </summary>
|
||||
public string CompressionAlgorithm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="EncryptingCredentials"/> used to create a encrypted security token.
|
||||
/// </summary>
|
||||
public EncryptingCredentials EncryptingCredentials { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the 'expiration' claim. This value should be in UTC.
|
||||
/// The expiration time is the sum of DateTime.Now and LifeTime.
|
||||
/// </summary>
|
||||
public DateTime? Expires => DateTime.Now.AddTicks(Lifetime.Ticks);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the issuer of this <see cref="SecurityTokenDescriptor"/>.
|
||||
/// </summary>
|
||||
public required string Issuer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the time the security token was issued. This value should be in UTC.
|
||||
/// </summary>
|
||||
public DateTime? IssuedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the notbefore time for the security token. This value should be in UTC.
|
||||
/// </summary>
|
||||
public DateTime? NotBefore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the token type.
|
||||
/// <remarks> 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 <see cref="AdditionalHeaderClaims"/> 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</remarks>
|
||||
/// </summary>
|
||||
public string TokenType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Dictionary{TKey, TValue}"/> 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 <see cref="SigningCredentials"/>,
|
||||
/// <see cref="EncryptingCredentials"/>, and/or <see cref="CompressionAlgorithm"/> provided and SHOULD NOT be included in this dictionary as this
|
||||
/// will result in an exception being thrown.
|
||||
/// <remarks> These claims are only added to the outer header (in case of a JWE).</remarks>
|
||||
/// </summary>
|
||||
public IDictionary<string, object> AdditionalHeaderClaims { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Dictionary{TKey, TValue}"/> 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 <see cref="SigningCredentials"/>,
|
||||
/// <see cref="EncryptingCredentials"/>, and/or <see cref="CompressionAlgorithm"/> provided and SHOULD NOT be included in this dictionary as this
|
||||
/// will result in an exception being thrown.
|
||||
/// <remarks>
|
||||
/// For JsonWebTokenHandler, these claims are merged with <see cref="AdditionalHeaderClaims"/> while adding to the inner JWT header.
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
public IDictionary<string, object> AdditionalInnerHeaderClaims { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="SigningCredentials"/> used to create a security token.
|
||||
/// </summary>
|
||||
public SigningCredentials SigningCredentials => _lazySigningCredentials.Value;
|
||||
#endregion SecurityTokenDescriptor
|
||||
|
||||
private readonly Lazy<RsaSecurityKey> _lazyRsaSecurityKey;
|
||||
|
||||
public SecurityKey SecurityKey => _lazyRsaSecurityKey.Value;
|
||||
|
||||
private readonly Lazy<SigningCredentials> _lazySigningCredentials;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the signature algorithm to be applied to the <see cref="SigningCredentials"/>.
|
||||
/// Default is <see cref="SecurityAlgorithms.RsaSha256"/>.
|
||||
/// </summary>
|
||||
public string SigningAlgorithm { get; init; } = SecurityAlgorithms.RsaSha256;
|
||||
|
||||
/// <summary>
|
||||
/// Optionally specifies the digest algorithm to be applied during the signing process for the <see cref="SigningCredentials"/>.
|
||||
/// If not provided, the default algorithm is used.
|
||||
/// </summary>
|
||||
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.
|
||||
{
|
||||
_lazyTokenValidator = new(CreatePublicKey<RSATokenValidator>);
|
||||
|
||||
_lazyRsaSecurityKey = new(() => new RsaSecurityKey(RSA));
|
||||
|
||||
_lazySigningCredentials = new(() => SigningDigest is null
|
||||
? new(SecurityKey, SigningAlgorithm)
|
||||
: new(SecurityKey, SigningAlgorithm, SigningDigest));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace DigitalData.Core.Security.RSAKey
|
||||
{
|
||||
public class RSATokenValidator : RSAPublicKey, IAsymmetricTokenValidator
|
||||
{
|
||||
private readonly Lazy<RsaSecurityKey> _lazyRsaSecurityKey;
|
||||
|
||||
public SecurityKey SecurityKey => _lazyRsaSecurityKey.Value;
|
||||
|
||||
public RSATokenValidator()
|
||||
{
|
||||
_lazyRsaSecurityKey = new(() => new RsaSecurityKey(RSA));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using DigitalData.Core.Security.Config;
|
||||
using DigitalData.Core.Security.RSAKey;
|
||||
using DigitalData.Core.Security.RSAKey.Auth;
|
||||
using DigitalData.Core.Security.RSAKey.Base;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.Config;
|
||||
using DigitalData.Core.Security.RSAKey;
|
||||
using DigitalData.Core.Security.RSAKey.Crypto;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security.Services;
|
||||
|
||||
Reference in New Issue
Block a user