From fcb169e6673c3bd35a3e4c36e07cdaa927bfb45c Mon Sep 17 00:00:00 2001 From: hyh Date: Tue, 10 Jun 2025 15:46:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=EF=BC=8C=E6=8C=89?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=A8=A1=E5=9D=97=E5=88=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => Authentication}/JwtProvider.cs | 2 +- .../Authentication/JwtValidationService.cs | 134 +++++++++++++++++ .../KeyRotationBackgroundService.cs | 2 +- .../KeyRotationService.cs | 2 +- .../{ => Infrastructure}/CacheService.cs | 2 +- .../DistributedLockService.cs | 2 +- .../Services/JwtValidationService.cs | 135 ------------------ .../Services/{ => Security}/CaptchaService.cs | 2 +- .../CaptchaVerificationService.cs | 2 +- .../{ => UserManagement}/EmailService.cs | 2 +- .../EmailVerificationService.cs | 2 +- .../UserRegistrationService.cs | 2 +- 12 files changed, 144 insertions(+), 145 deletions(-) rename src/CellularManagement.Infrastructure/Services/{ => Authentication}/JwtProvider.cs (99%) create mode 100644 src/CellularManagement.Infrastructure/Services/Authentication/JwtValidationService.cs rename src/CellularManagement.Infrastructure/Services/{ => Authentication}/KeyRotationBackgroundService.cs (96%) rename src/CellularManagement.Infrastructure/Services/{ => Authentication}/KeyRotationService.cs (98%) rename src/CellularManagement.Infrastructure/Services/{ => Infrastructure}/CacheService.cs (95%) rename src/CellularManagement.Infrastructure/Services/{ => Infrastructure}/DistributedLockService.cs (98%) delete mode 100644 src/CellularManagement.Infrastructure/Services/JwtValidationService.cs rename src/CellularManagement.Infrastructure/Services/{ => Security}/CaptchaService.cs (97%) rename src/CellularManagement.Infrastructure/Services/{ => Security}/CaptchaVerificationService.cs (97%) rename src/CellularManagement.Infrastructure/Services/{ => UserManagement}/EmailService.cs (98%) rename src/CellularManagement.Infrastructure/Services/{ => UserManagement}/EmailVerificationService.cs (98%) rename src/CellularManagement.Infrastructure/Services/{ => UserManagement}/UserRegistrationService.cs (98%) diff --git a/src/CellularManagement.Infrastructure/Services/JwtProvider.cs b/src/CellularManagement.Infrastructure/Services/Authentication/JwtProvider.cs similarity index 99% rename from src/CellularManagement.Infrastructure/Services/JwtProvider.cs rename to src/CellularManagement.Infrastructure/Services/Authentication/JwtProvider.cs index afcfd11..06d5bd0 100644 --- a/src/CellularManagement.Infrastructure/Services/JwtProvider.cs +++ b/src/CellularManagement.Infrastructure/Services/Authentication/JwtProvider.cs @@ -10,7 +10,7 @@ using System.Text.Json; using CellularManagement.Domain.Services; using CellularManagement.Domain.Options; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.Authentication; /// /// JWT 令牌提供者实现 diff --git a/src/CellularManagement.Infrastructure/Services/Authentication/JwtValidationService.cs b/src/CellularManagement.Infrastructure/Services/Authentication/JwtValidationService.cs new file mode 100644 index 0000000..1a380d2 --- /dev/null +++ b/src/CellularManagement.Infrastructure/Services/Authentication/JwtValidationService.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CellularManagement.Domain.Options; +using CellularManagement.Domain.Services; + +namespace CellularManagement.Infrastructure.Services.Authentication; + +/// +/// JWT 验证服务实现 +/// +public class JwtValidationService : IJwtValidationService +{ + /// + public void ValidateOptions(JwtOptions options) + { + if (string.IsNullOrEmpty(options.SecretKey)) + { + throw new ArgumentException("JWT密钥不能为空"); + } + + if (string.IsNullOrEmpty(options.Issuer)) + { + throw new ArgumentException("JWT颁发者不能为空"); + } + + if (string.IsNullOrEmpty(options.Audience)) + { + throw new ArgumentException("JWT受众不能为空"); + } + + if (options.ExpiryMinutes <= 0) + { + throw new ArgumentException("JWT过期时间必须大于0"); + } + + if (options.RefreshTokenExpiryDays <= 0) + { + throw new ArgumentException("刷新令牌过期时间必须大于0"); + } + + if (options.ClockSkewMinutes < 0) + { + throw new ArgumentException("时钟偏差不能为负数"); + } + + if (options.KeyRotationDays <= 0) + { + throw new ArgumentException("密钥轮换间隔必须大于0"); + } + + if (options.MinKeyLength < 32) + { + throw new ArgumentException("密钥最小长度必须至少为32字节"); + } + + // 验证密钥是否为有效的Base64字符串 + try + { + var keyBytes = Convert.FromBase64String(options.SecretKey); + if (keyBytes.Length < options.MinKeyLength) + { + throw new ArgumentException($"密钥长度必须至少为{options.MinKeyLength}字节"); + } + } + catch (FormatException) + { + throw new ArgumentException("JWT密钥不是有效的Base64字符串"); + } + } + + + + /// + public void ValidateKeyStrength(string secretKey, int minKeyLength) + { + if (string.IsNullOrEmpty(secretKey)) + { + throw new ArgumentException("密钥不能为空"); + } + + // 验证密钥是否为有效的Base64字符串 + try + { + var keyBytes = Convert.FromBase64String(secretKey); + if (keyBytes.Length < minKeyLength) + { + throw new ArgumentException($"密钥长度必须至少为 {minKeyLength} 字节"); + } + } + catch (FormatException) + { + throw new ArgumentException("密钥不是有效的Base64字符串"); + } + + // 检查密钥是否包含足够的随机性 + var entropy = CalculateEntropy(secretKey); + if (entropy < 3.5) // 3.5 bits per character is considered good + { + throw new ArgumentException("密钥随机性不足"); + } + } + + /// + /// 计算字符串熵值 + /// + private static double CalculateEntropy(string input) + { + var charCounts = new Dictionary(); + foreach (var c in input) + { + if (charCounts.ContainsKey(c)) + { + charCounts[c]++; + } + else + { + charCounts[c] = 1; + } + } + + var length = input.Length; + var entropy = 0.0; + foreach (var count in charCounts.Values) + { + var probability = (double)count / length; + entropy -= probability * Math.Log2(probability); + } + + return entropy; + } +} diff --git a/src/CellularManagement.Infrastructure/Services/KeyRotationBackgroundService.cs b/src/CellularManagement.Infrastructure/Services/Authentication/KeyRotationBackgroundService.cs similarity index 96% rename from src/CellularManagement.Infrastructure/Services/KeyRotationBackgroundService.cs rename to src/CellularManagement.Infrastructure/Services/Authentication/KeyRotationBackgroundService.cs index 6d00c22..5f42f72 100644 --- a/src/CellularManagement.Infrastructure/Services/KeyRotationBackgroundService.cs +++ b/src/CellularManagement.Infrastructure/Services/Authentication/KeyRotationBackgroundService.cs @@ -5,7 +5,7 @@ using CellularManagement.Domain.Services; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.Authentication; /// /// 密钥轮换后台服务 diff --git a/src/CellularManagement.Infrastructure/Services/KeyRotationService.cs b/src/CellularManagement.Infrastructure/Services/Authentication/KeyRotationService.cs similarity index 98% rename from src/CellularManagement.Infrastructure/Services/KeyRotationService.cs rename to src/CellularManagement.Infrastructure/Services/Authentication/KeyRotationService.cs index 7f7abf5..b735871 100644 --- a/src/CellularManagement.Infrastructure/Services/KeyRotationService.cs +++ b/src/CellularManagement.Infrastructure/Services/Authentication/KeyRotationService.cs @@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging; using CellularManagement.Domain.Services; using CellularManagement.Domain.Options; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.Authentication; /// /// 密钥轮换服务实现 diff --git a/src/CellularManagement.Infrastructure/Services/CacheService.cs b/src/CellularManagement.Infrastructure/Services/Infrastructure/CacheService.cs similarity index 95% rename from src/CellularManagement.Infrastructure/Services/CacheService.cs rename to src/CellularManagement.Infrastructure/Services/Infrastructure/CacheService.cs index b4a4530..0b6a836 100644 --- a/src/CellularManagement.Infrastructure/Services/CacheService.cs +++ b/src/CellularManagement.Infrastructure/Services/Infrastructure/CacheService.cs @@ -1,7 +1,7 @@ using CellularManagement.Domain.Services; using Microsoft.Extensions.Caching.Memory; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.Infrastructure; /// /// 内存缓存服务实现 diff --git a/src/CellularManagement.Infrastructure/Services/DistributedLockService.cs b/src/CellularManagement.Infrastructure/Services/Infrastructure/DistributedLockService.cs similarity index 98% rename from src/CellularManagement.Infrastructure/Services/DistributedLockService.cs rename to src/CellularManagement.Infrastructure/Services/Infrastructure/DistributedLockService.cs index 8074dde..479930f 100644 --- a/src/CellularManagement.Infrastructure/Services/DistributedLockService.cs +++ b/src/CellularManagement.Infrastructure/Services/Infrastructure/DistributedLockService.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; using CellularManagement.Domain.Services; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.Infrastructure; /// /// 分布式锁服务实现 diff --git a/src/CellularManagement.Infrastructure/Services/JwtValidationService.cs b/src/CellularManagement.Infrastructure/Services/JwtValidationService.cs deleted file mode 100644 index 160fc91..0000000 --- a/src/CellularManagement.Infrastructure/Services/JwtValidationService.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CellularManagement.Domain.Options; -using CellularManagement.Domain.Services; - -namespace CellularManagement.Infrastructure.Services -{ - /// - /// JWT 验证服务实现 - /// - public class JwtValidationService : IJwtValidationService - { - /// - public void ValidateOptions(JwtOptions options) - { - if (string.IsNullOrEmpty(options.SecretKey)) - { - throw new ArgumentException("JWT密钥不能为空"); - } - - if (string.IsNullOrEmpty(options.Issuer)) - { - throw new ArgumentException("JWT颁发者不能为空"); - } - - if (string.IsNullOrEmpty(options.Audience)) - { - throw new ArgumentException("JWT受众不能为空"); - } - - if (options.ExpiryMinutes <= 0) - { - throw new ArgumentException("JWT过期时间必须大于0"); - } - - if (options.RefreshTokenExpiryDays <= 0) - { - throw new ArgumentException("刷新令牌过期时间必须大于0"); - } - - if (options.ClockSkewMinutes < 0) - { - throw new ArgumentException("时钟偏差不能为负数"); - } - - if (options.KeyRotationDays <= 0) - { - throw new ArgumentException("密钥轮换间隔必须大于0"); - } - - if (options.MinKeyLength < 32) - { - throw new ArgumentException("密钥最小长度必须至少为32字节"); - } - - // 验证密钥是否为有效的Base64字符串 - try - { - var keyBytes = Convert.FromBase64String(options.SecretKey); - if (keyBytes.Length < options.MinKeyLength) - { - throw new ArgumentException($"密钥长度必须至少为{options.MinKeyLength}字节"); - } - } - catch (FormatException) - { - throw new ArgumentException("JWT密钥不是有效的Base64字符串"); - } - } - - - - /// - public void ValidateKeyStrength(string secretKey, int minKeyLength) - { - if (string.IsNullOrEmpty(secretKey)) - { - throw new ArgumentException("密钥不能为空"); - } - - // 验证密钥是否为有效的Base64字符串 - try - { - var keyBytes = Convert.FromBase64String(secretKey); - if (keyBytes.Length < minKeyLength) - { - throw new ArgumentException($"密钥长度必须至少为 {minKeyLength} 字节"); - } - } - catch (FormatException) - { - throw new ArgumentException("密钥不是有效的Base64字符串"); - } - - // 检查密钥是否包含足够的随机性 - var entropy = CalculateEntropy(secretKey); - if (entropy < 3.5) // 3.5 bits per character is considered good - { - throw new ArgumentException("密钥随机性不足"); - } - } - - /// - /// 计算字符串熵值 - /// - private static double CalculateEntropy(string input) - { - var charCounts = new Dictionary(); - foreach (var c in input) - { - if (charCounts.ContainsKey(c)) - { - charCounts[c]++; - } - else - { - charCounts[c] = 1; - } - } - - var length = input.Length; - var entropy = 0.0; - foreach (var count in charCounts.Values) - { - var probability = (double)count / length; - entropy -= probability * Math.Log2(probability); - } - - return entropy; - } - } -} diff --git a/src/CellularManagement.Infrastructure/Services/CaptchaService.cs b/src/CellularManagement.Infrastructure/Services/Security/CaptchaService.cs similarity index 97% rename from src/CellularManagement.Infrastructure/Services/CaptchaService.cs rename to src/CellularManagement.Infrastructure/Services/Security/CaptchaService.cs index 2c33ebc..3a4dafd 100644 --- a/src/CellularManagement.Infrastructure/Services/CaptchaService.cs +++ b/src/CellularManagement.Infrastructure/Services/Security/CaptchaService.cs @@ -1,7 +1,7 @@ using CellularManagement.Domain.Services; using SkiaSharp; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.Security; public class CaptchaService : ICaptchaService { diff --git a/src/CellularManagement.Infrastructure/Services/CaptchaVerificationService.cs b/src/CellularManagement.Infrastructure/Services/Security/CaptchaVerificationService.cs similarity index 97% rename from src/CellularManagement.Infrastructure/Services/CaptchaVerificationService.cs rename to src/CellularManagement.Infrastructure/Services/Security/CaptchaVerificationService.cs index db07836..3b30a8d 100644 --- a/src/CellularManagement.Infrastructure/Services/CaptchaVerificationService.cs +++ b/src/CellularManagement.Infrastructure/Services/Security/CaptchaVerificationService.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.Logging; using CellularManagement.Domain.Services; using CellularManagement.Domain.Common; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.Security; /// /// 验证码验证服务实现 diff --git a/src/CellularManagement.Infrastructure/Services/EmailService.cs b/src/CellularManagement.Infrastructure/Services/UserManagement/EmailService.cs similarity index 98% rename from src/CellularManagement.Infrastructure/Services/EmailService.cs rename to src/CellularManagement.Infrastructure/Services/UserManagement/EmailService.cs index 2e8b208..3c43239 100644 --- a/src/CellularManagement.Infrastructure/Services/EmailService.cs +++ b/src/CellularManagement.Infrastructure/Services/UserManagement/EmailService.cs @@ -9,7 +9,7 @@ using MailKit.Security; using Microsoft.Extensions.Options; using MimeKit; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.UserManagement; /// /// 邮箱服务实现类 diff --git a/src/CellularManagement.Infrastructure/Services/EmailVerificationService.cs b/src/CellularManagement.Infrastructure/Services/UserManagement/EmailVerificationService.cs similarity index 98% rename from src/CellularManagement.Infrastructure/Services/EmailVerificationService.cs rename to src/CellularManagement.Infrastructure/Services/UserManagement/EmailVerificationService.cs index 5500119..0d2928a 100644 --- a/src/CellularManagement.Infrastructure/Services/EmailVerificationService.cs +++ b/src/CellularManagement.Infrastructure/Services/UserManagement/EmailVerificationService.cs @@ -6,7 +6,7 @@ using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using CellularManagement.Domain.Options; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.UserManagement; /// /// 邮箱验证码服务 diff --git a/src/CellularManagement.Infrastructure/Services/UserRegistrationService.cs b/src/CellularManagement.Infrastructure/Services/UserManagement/UserRegistrationService.cs similarity index 98% rename from src/CellularManagement.Infrastructure/Services/UserRegistrationService.cs rename to src/CellularManagement.Infrastructure/Services/UserManagement/UserRegistrationService.cs index e404322..e7bea13 100644 --- a/src/CellularManagement.Infrastructure/Services/UserRegistrationService.cs +++ b/src/CellularManagement.Infrastructure/Services/UserManagement/UserRegistrationService.cs @@ -11,7 +11,7 @@ using CellularManagement.Domain.Repositories; using System.Threading; using CellularManagement.Domain.Repositories.Identity; -namespace CellularManagement.Infrastructure.Services; +namespace CellularManagement.Infrastructure.Services.UserManagement; /// /// 用户注册领域服务实现