diff --git a/Directory.Packages.props b/Directory.Packages.props index b9d54b3e0..7ef269c33 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -333,6 +333,10 @@ + + + + diff --git a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj index c9604faa5..fd6b3232a 100644 --- a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj +++ b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj @@ -25,7 +25,7 @@ - + diff --git a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AcsClientFactory.cs b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AcsClientFactory.cs deleted file mode 100644 index 4401aee25..000000000 --- a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AcsClientFactory.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Aliyun.Acs.Core; -using Aliyun.Acs.Core.Auth; -using Aliyun.Acs.Core.Profile; -using LINGYUN.Abp.Aliyun.Features; -using Volo.Abp.Caching; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Features; -using Volo.Abp.Settings; - -namespace LINGYUN.Abp.Aliyun; - -[RequiresFeature(AliyunFeatureNames.Enable)] -public class AcsClientFactory : AliyunClientFactory, IAcsClientFactory, ITransientDependency -{ - public AcsClientFactory( - ISettingProvider settingProvider, - IDistributedCache cache) - : base(settingProvider, cache) - { - } - - protected override IAcsClient GetClient(string regionId, string accessKeyId, string accessKeySecret) - { - return new DefaultAcsClient( - DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret)); - } - - protected override IAcsClient GetSecurityTokenClient(string regionId, string accessKeyId, string accessKeySecret, string securityToken) - { - var profile = DefaultProfile.GetProfile(regionId); - var credentials = new BasicSessionCredentials(accessKeyId, accessKeySecret, securityToken); - return new DefaultAcsClient(profile, credentials); - } -} diff --git a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunBasicSessionCredentialsCacheItem.cs b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunBasicSessionCredentialsCacheItem.cs index 41630d221..8533d6ed0 100644 --- a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunBasicSessionCredentialsCacheItem.cs +++ b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunBasicSessionCredentialsCacheItem.cs @@ -5,26 +5,21 @@ namespace LINGYUN.Abp.Aliyun; [Serializable] public class AliyunBasicSessionCredentialsCacheItem { - private readonly static string _cacheKey; - public static string CacheKey => _cacheKey; public string AccessKeyId { get; set; } public string AccessKeySecret { get; set; } public string SecurityToken { get; set; } - - static AliyunBasicSessionCredentialsCacheItem() - { - _cacheKey = Guid.NewGuid().ToString("N"); - } + public DateTime? Expiration { get; set; } public AliyunBasicSessionCredentialsCacheItem() { } - public AliyunBasicSessionCredentialsCacheItem(string accessKeyId, string accessKeySecret, string securityToken) + public AliyunBasicSessionCredentialsCacheItem(string accessKeyId, string accessKeySecret, string securityToken, DateTime? expiration = null) { AccessKeyId = accessKeyId; AccessKeySecret = accessKeySecret; SecurityToken = securityToken; + Expiration = expiration; } } diff --git a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunClientFactory.cs b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunClientFactory.cs index df800cb11..f87b007ca 100644 --- a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunClientFactory.cs +++ b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunClientFactory.cs @@ -1,14 +1,12 @@ -using Aliyun.Acs.Core; -using Aliyun.Acs.Core.Auth.Sts; -using Aliyun.Acs.Core.Http; -using Aliyun.Acs.Core.Profile; -using LINGYUN.Abp.Aliyun.Settings; +using LINGYUN.Abp.Aliyun.Settings; using Microsoft.Extensions.Caching.Distributed; using System; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Caching; using Volo.Abp.Settings; +using OpenApiConfig = AlibabaCloud.OpenApiClient.Models.Config; +using StsClient = AlibabaCloud.SDK.Sts20150401.Client; namespace LINGYUN.Abp.Aliyun; @@ -42,19 +40,33 @@ public abstract class AliyunClientFactory { var cacheItem = await GetCacheItemAsync(accessKey, accessKeySecret, regionId); - return GetSecurityTokenClient(regionId, cacheItem.AccessKeyId, cacheItem.AccessKeySecret, cacheItem.SecurityToken); + return GetSecurityTokenClient( + regionId, + cacheItem.AccessKeyId, + cacheItem.AccessKeySecret, + cacheItem.SecurityToken, + cacheItem.Expiration); } return GetClient(regionId, accessKey, accessKeySecret); } - protected abstract TClient GetClient(string regionId, string accessKeyId, string accessKeySecret); + protected abstract TClient GetClient( + string regionId, + string accessKeyId, + string accessKeySecret); - protected abstract TClient GetSecurityTokenClient(string regionId, string accessKeyId, string accessKeySecret, string securityToken); + protected abstract TClient GetSecurityTokenClient( + string regionId, + string accessKeyId, + string accessKeySecret, + string securityToken, + DateTime? expiration = null); protected async virtual Task GetCacheItemAsync(string accessKeyId, string accessKeySecret, string regionId) { - var cacheItem = await Cache.GetAsync(AliyunBasicSessionCredentialsCacheItem.CacheKey); + var cacheKey = $"{accessKeyId}:{accessKeySecret}".ToMd5(); + var cacheItem = await Cache.GetAsync(cacheKey); if (cacheItem == null) { var roleArn = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RamRoleArn); @@ -64,30 +76,41 @@ public abstract class AliyunClientFactory var policy = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.Policy); var durationSeconds = await SettingProvider.GetAsync(AliyunSettingNames.Authorization.DurationSeconds, 3000); - var profile = DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret); - var request = new AssumeRoleRequest - { - AcceptFormat = FormatType.JSON, - RoleArn = roleArn, - RoleSessionName = roleSession, - DurationSeconds = durationSeconds, - Policy = policy.IsNullOrWhiteSpace() ? null : policy - }; + var stsClient = new StsClient( + new OpenApiConfig + { + RegionId = regionId, + AccessKeyId = accessKeyId, + AccessKeySecret = accessKeySecret, + }); - var client = new DefaultAcsClient(profile); - var response = client.GetAcsResponse(request); + var assumeRoleResponse = await stsClient.AssumeRoleAsync( + new AlibabaCloud.SDK.Sts20150401.Models.AssumeRoleRequest + { + RoleArn = roleArn, + RoleSessionName = roleSession, + DurationSeconds = durationSeconds, + Policy = policy.IsNullOrWhiteSpace() ? null : policy, + }); cacheItem = new AliyunBasicSessionCredentialsCacheItem( - response.Credentials.AccessKeyId, - response.Credentials.AccessKeySecret, - response.Credentials.SecurityToken); + assumeRoleResponse.Body.Credentials.AccessKeyId, + assumeRoleResponse.Body.Credentials.AccessKeySecret, + assumeRoleResponse.Body.Credentials.SecurityToken); + + var expirationTimeSpan = TimeSpan.FromSeconds(durationSeconds - 10); + if (DateTime.TryParse(assumeRoleResponse.Body.Credentials.Expiration, out var expiration)) + { + cacheItem.Expiration = expiration; + expirationTimeSpan = new TimeSpan(expiration.AddSeconds(-10).Ticks); + } await Cache.SetAsync( - AliyunBasicSessionCredentialsCacheItem.CacheKey, + cacheKey, cacheItem, new DistributedCacheEntryOptions { - AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(durationSeconds - 10) + AbsoluteExpirationRelativeToNow = expirationTimeSpan, }); } @@ -122,13 +145,29 @@ public abstract class AliyunClientFactory : AliyunClien { var cacheItem = await GetCacheItemAsync(accessKey, accessKeySecret, regionId); - return GetSecurityTokenClient(configuration, regionId, cacheItem.AccessKeyId, cacheItem.AccessKeySecret, cacheItem.SecurityToken); + return GetSecurityTokenClient( + configuration, + regionId, + cacheItem.AccessKeyId, + cacheItem.AccessKeySecret, + cacheItem.SecurityToken, + cacheItem.Expiration); } return GetClient(configuration, regionId, accessKey, accessKeySecret); } - protected abstract TClient GetClient(TConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret); - - protected abstract TClient GetSecurityTokenClient(TConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret, string securityToken); + protected abstract TClient GetClient( + TConfiguration configuration, + string regionId, + string accessKeyId, + string accessKeySecret); + + protected abstract TClient GetSecurityTokenClient( + TConfiguration configuration, + string regionId, + string accessKeyId, + string accessKeySecret, + string securityToken, + DateTime? expiration = null); } diff --git a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/IAcsClientFactory.cs b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/IAcsClientFactory.cs deleted file mode 100644 index bf81b77c1..000000000 --- a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/IAcsClientFactory.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Aliyun.Acs.Core; -using System.Threading.Tasks; - -namespace LINGYUN.Abp.Aliyun; - -public interface IAcsClientFactory -{ - /// - /// 构造一个通用的Acs客户端调用 - /// 通过CommonRequest调用可以不需要集成其他SDK包 - /// - /// - Task CreateAsync(); -} diff --git a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Settings/AliyunSettingProvider.cs b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Settings/AliyunSettingProvider.cs index 5e5f98805..955594a6a 100644 --- a/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Settings/AliyunSettingProvider.cs +++ b/aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Settings/AliyunSettingProvider.cs @@ -79,7 +79,7 @@ public class AliyunSettingProvider : SettingDefinitionProvider TenantSettingValueProvider.ProviderName), new SettingDefinition( AliyunSettingNames.Authorization.RegionId, - defaultValue: "oss-cn-hangzhou", + defaultValue: "cn-hangzhou", displayName: L("DisplayName:RegionId"), description: L("Description:RegionId"), isVisibleToClients: false diff --git a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN.Abp.BlobStoring.Aliyun.csproj b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN.Abp.BlobStoring.Aliyun.csproj index 59822d893..7f8460f95 100644 --- a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN.Abp.BlobStoring.Aliyun.csproj +++ b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN.Abp.BlobStoring.Aliyun.csproj @@ -15,7 +15,7 @@ - + diff --git a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs index 0064ce2cc..af8bd175d 100644 --- a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs +++ b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs @@ -1,29 +1,33 @@ -using Aliyun.OSS; +using AlibabaCloud.OSS.V2; +using AlibabaCloud.OSS.V2.Models; using LINGYUN.Abp.Aliyun.Features; using Microsoft.Extensions.DependencyInjection; using System; -using System.Collections.Generic; using System.IO; using System.Net.Http; using System.Threading.Tasks; using Volo.Abp.BlobStoring; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; +using Volo.Abp.Timing; namespace LINGYUN.Abp.BlobStoring.Aliyun; [RequiresFeature(AliyunFeatureNames.BlobStoring.Enable)] public class AliyunBlobProvider : BlobProviderBase, ITransientDependency { + protected IClock Clock { get; } protected IOssClientFactory OssClientFactory { get; } protected IHttpClientFactory HttpClientFactory { get; } protected IAliyunBlobNameCalculator AliyunBlobNameCalculator { get; } public AliyunBlobProvider( + IClock clock, IOssClientFactory ossClientFactory, IHttpClientFactory httpClientFactory, IAliyunBlobNameCalculator aliyunBlobNameCalculator) { + Clock = clock; OssClientFactory = ossClientFactory; HttpClientFactory = httpClientFactory; AliyunBlobNameCalculator = aliyunBlobNameCalculator; @@ -36,7 +40,14 @@ public class AliyunBlobProvider : BlobProviderBase, ITransientDependency if (await BlobExistsAsync(ossClient, args, blobName)) { - return ossClient.DeleteObject(GetBucketName(args), blobName).DeleteMarker; + var deleteObjectRes = await ossClient.DeleteObjectAsync( + new DeleteObjectRequest + { + Bucket = GetBucketName(args), + Key = blobName, + }, + cancellationToken: args.CancellationToken); + return deleteObjectRes.DeleteMarker == true; } return false; @@ -60,11 +71,27 @@ public class AliyunBlobProvider : BlobProviderBase, ITransientDependency return null; } - var downloadUri = ossClient.GeneratePresignedUri(GetBucketName(args), blobName); - - var httpClient = HttpClientFactory.CreateAliyunHttpClient(); - - return await httpClient.GetStreamAsync(downloadUri, args.CancellationToken); + var result = await ossClient.GetObjectAsync( + new GetObjectRequest + { + Bucket = GetBucketName(args), + Key = blobName, + }); + return result.Body; + + // TODO: 阿里云sdk预签名不可用[2026/05/23] + //var configuration = args.Configuration.GetAliyunConfiguration(); + //var presignResult = ossClient.Presign( + // new GetObjectRequest + // { + // Bucket = GetBucketName(args), + // Key = blobName, + // }, + // Clock.Now.AddSeconds(configuration.PresignedGetExpirySeconds)); + + //var httpClient = HttpClientFactory.CreateAliyunHttpClient(); + + //return await httpClient.GetStreamAsync(presignResult.Url, args.CancellationToken); } public override async Task SaveAsync(BlobProviderSaveArgs args) @@ -76,7 +103,7 @@ public class AliyunBlobProvider : BlobProviderBase, ITransientDependency // 先检查Bucket if (configuration.CreateBucketIfNotExists) { - await CreateBucketIfNotExists(ossClient, args, configuration.CreateBucketReferer); + await CreateBucketIfNotExists(ossClient, args, configuration.CreateBucketAcl); } var bucketName = GetBucketName(args); @@ -92,60 +119,70 @@ public class AliyunBlobProvider : BlobProviderBase, ITransientDependency else { // 删除原文件 - ossClient.DeleteObject(bucketName, blobName); + await ossClient.DeleteObjectAsync( + new DeleteObjectRequest + { + Bucket = bucketName, + Key = blobName, + }, + cancellationToken: args.CancellationToken); } } // 保存 - ossClient.PutObject(bucketName, blobName, args.BlobStream); + await ossClient.PutObjectAsync( + new PutObjectRequest + { + Bucket = bucketName, + Key = blobName, + Body = args.BlobStream, + }, + cancellationToken: args.CancellationToken); } - protected async virtual Task GetOssClientAsync(BlobProviderArgs args) + protected async virtual Task GetOssClientAsync(BlobProviderArgs args) { - var ossClient = await OssClientFactory.CreateAsync(); - return ossClient; + return await OssClientFactory.CreateAsync(); } - protected async virtual Task CreateBucketIfNotExists(IOss ossClient, BlobProviderArgs args, IList refererList = null) + protected async virtual Task CreateBucketIfNotExists(Client ossClient, BlobProviderArgs args, BucketAclType? bucketAcl = null) { - if (! await BucketExistsAsync(ossClient, args)) + if (!await BucketExistsAsync(ossClient, args)) { var bucketName = GetBucketName(args); - var request = new CreateBucketRequest(bucketName) - { - //设置存储空间访问权限ACL。 - ACL = CannedAccessControlList.PublicReadWrite, - //设置数据容灾类型。 - DataRedundancyType = DataRedundancyType.ZRS - }; - - ossClient.CreateBucket(request); + await ossClient.PutBucketAsync( + new PutBucketRequest + { + Bucket = bucketName, + }, + cancellationToken: args.CancellationToken); - if (refererList != null && refererList.Count > 0) + if (bucketAcl.HasValue) { - var srq = new SetBucketRefererRequest(bucketName, refererList); - ossClient.SetBucketReferer(srq); + await ossClient.PutBucketAclAsync( + new PutBucketAclRequest + { + Bucket = bucketName, + Acl = bucketAcl.Value.GetString(), + }, + cancellationToken: args.CancellationToken); } } } - private async Task BlobExistsAsync(IOss ossClient, BlobProviderArgs args, string blobName) + private async Task BlobExistsAsync(Client ossClient, BlobProviderArgs args, string blobName) { var bucketExists = await BucketExistsAsync(ossClient, args); if (bucketExists) { - var objectExists = ossClient.DoesObjectExist(GetBucketName(args), blobName); - - return objectExists; + return await ossClient.IsObjectExistAsync(GetBucketName(args), blobName, cancellationToken: args.CancellationToken); } return false; } - private Task BucketExistsAsync(IOss ossClient, BlobProviderArgs args) + private async Task BucketExistsAsync(Client ossClient, BlobProviderArgs args) { - var bucketExists = ossClient.DoesBucketExist(GetBucketName(args)); - - return Task.FromResult(bucketExists); + return await ossClient.IsBucketExistAsync(GetBucketName(args), args.CancellationToken); } private static string GetBucketName(BlobProviderArgs args) diff --git a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfiguration.cs b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfiguration.cs index d7efa95a4..2401174e1 100644 --- a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfiguration.cs +++ b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfiguration.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using AlibabaCloud.OSS.V2.Models; +using System.Collections.Generic; using Volo.Abp.BlobStoring; namespace LINGYUN.Abp.BlobStoring.Aliyun; @@ -14,6 +15,13 @@ public class AliyunBlobProviderConfiguration set => _containerConfiguration.SetConfiguration(AliyunBlobProviderConfigurationNames.BucketName, value); } /// + /// 跳过服务器证书验证 + /// + public bool InsecureSkipVerify { + get => _containerConfiguration.GetConfigurationOrDefault(AliyunBlobProviderConfigurationNames.InsecureSkipVerify, false); + set => _containerConfiguration.SetConfiguration(AliyunBlobProviderConfigurationNames.InsecureSkipVerify, value); + } + /// /// 命名空间不存在是否创建 /// public bool CreateBucketIfNotExists @@ -22,11 +30,18 @@ public class AliyunBlobProviderConfiguration set => _containerConfiguration.SetConfiguration(AliyunBlobProviderConfigurationNames.CreateBucketIfNotExists, value); } /// + /// 创建命名空间时的Acl + /// + public BucketAclType? CreateBucketAcl { + get => _containerConfiguration.GetConfigurationOrDefault(AliyunBlobProviderConfigurationNames.CreateBucketAcl); + set => _containerConfiguration.SetConfiguration(AliyunBlobProviderConfigurationNames.CreateBucketAcl, value); + } + /// /// 创建命名空间时防盗链列表 /// public List CreateBucketReferer { - get => _containerConfiguration.GetConfiguration>(AliyunBlobProviderConfigurationNames.CreateBucketReferer); + get => _containerConfiguration.GetConfigurationOrDefault(AliyunBlobProviderConfigurationNames.CreateBucketReferer, new List()); set { if (value == null) diff --git a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfigurationNames.cs b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfigurationNames.cs index e3e0c9221..d0bc9f7a7 100644 --- a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfigurationNames.cs +++ b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfigurationNames.cs @@ -11,6 +11,10 @@ public static class AliyunBlobProviderConfigurationNames /// public const string BucketName = "Aliyun:OSS:BucketName"; /// + /// 跳过服务器证书验证 + /// + public const string InsecureSkipVerify = "Aliyun:OSS:InsecureSkipVerify"; + /// /// 命名空间不存在是否创建 /// public const string CreateBucketIfNotExists = "Aliyun:OSS:CreateBucketIfNotExists"; @@ -19,6 +23,10 @@ public static class AliyunBlobProviderConfigurationNames /// public const string CreateBucketReferer = "Aliyun:OSS:CreateBucketReferer"; /// + /// 创建命名空间时的Acl + /// + public const string CreateBucketAcl = "Aliyun:OSS:CreateBucketAcl"; + /// /// 生成预签名Uri的过期时间(s) /// public const string PresignedGetExpirySeconds = "Aliyun:OSS:PresignedGetExpirySeconds"; diff --git a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/IOssClientFactory.cs b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/IOssClientFactory.cs index 6a4ccd6fa..7dea3e3d5 100644 --- a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/IOssClientFactory.cs +++ b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/IOssClientFactory.cs @@ -1,4 +1,4 @@ -using Aliyun.OSS; +using AlibabaCloud.OSS.V2; using System.Threading.Tasks; namespace LINGYUN.Abp.BlobStoring.Aliyun; @@ -9,11 +9,11 @@ public interface IOssClientFactory /// 构建Oss客户端 /// /// - Task CreateAsync(); + Task CreateAsync(); /// /// 构建Oss客户端 /// /// /// - Task CreateAsync(AliyunBlobProviderConfiguration configuration); + Task CreateAsync(AliyunBlobProviderConfiguration configuration); } diff --git a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/OssClientFactory.cs b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/OssClientFactory.cs index 9388454f0..6fc4da256 100644 --- a/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/OssClientFactory.cs +++ b/aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/OssClientFactory.cs @@ -1,12 +1,14 @@ -using Aliyun.OSS; +using AlibabaCloud.OSS.V2; +using AlibabaCloud.OSS.V2.Credentials; using LINGYUN.Abp.Aliyun; +using System; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.Settings; namespace LINGYUN.Abp.BlobStoring.Aliyun; -public class OssClientFactory : AliyunClientFactory, IOssClientFactory, ITransientDependency +public class OssClientFactory : AliyunClientFactory, IOssClientFactory, ITransientDependency { public OssClientFactory( ISettingProvider settingProvider, @@ -22,12 +24,22 @@ public class OssClientFactory : AliyunClientFactory /// /// - protected override IOss GetClient(string regionId, string accessKeyId, string accessKeySecret) + protected override Client GetClient(string regionId, string accessKeyId, string accessKeySecret) { - return new OssClient( - regionId, - accessKeyId, - accessKeySecret); + + return new Client( + new Configuration + { + Region = regionId, + CredentialsProvider = new CredentialsProviderFunc(() => + { + return new Credentials(accessKeyId, accessKeySecret); + }), + }); + //return new OssClient( + // regionId, + // accessKeyId, + // accessKeySecret); } /// @@ -38,12 +50,18 @@ public class OssClientFactory : AliyunClientFactory /// /// - protected override IOss GetClient(AliyunBlobProviderConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret) + protected override Client GetClient(AliyunBlobProviderConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret) { - return new OssClient( - regionId, - accessKeyId, - accessKeySecret); + return new Client( + new Configuration + { + Region = regionId, + CredentialsProvider = new CredentialsProviderFunc(() => + { + return new Credentials(accessKeyId, accessKeySecret); + }), + InsecureSkipVerify = configuration.InsecureSkipVerify, + }); } /// @@ -54,13 +72,22 @@ public class OssClientFactory : AliyunClientFactory /// /// - protected override IOss GetSecurityTokenClient(string regionId, string accessKeyId, string accessKeySecret, string securityToken) + protected override Client GetSecurityTokenClient( + string regionId, + string accessKeyId, + string accessKeySecret, + string securityToken, + DateTime? expiration = null) { - return new OssClient( - regionId, - accessKeyId, - accessKeySecret, - securityToken); + return new Client( + new Configuration + { + Region = regionId, + CredentialsProvider = new CredentialsProviderFunc(() => + { + return new Credentials(accessKeyId, accessKeySecret, securityToken, expiration); + }), + }); } /// /// 通过用户安全令牌构建Oss客户端 @@ -71,12 +98,23 @@ public class OssClientFactory : AliyunClientFactory /// /// - protected override IOss GetSecurityTokenClient(AliyunBlobProviderConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret, string securityToken) + protected override Client GetSecurityTokenClient( + AliyunBlobProviderConfiguration configuration, + string regionId, + string accessKeyId, + string accessKeySecret, + string securityToken, + DateTime? expiration = null) { - return new OssClient( - regionId, - accessKeyId, - accessKeySecret, - securityToken); + return new Client( + new Configuration + { + Region = regionId, + CredentialsProvider = new CredentialsProviderFunc(() => + { + return new Credentials(accessKeyId, accessKeySecret, securityToken, expiration); + }), + InsecureSkipVerify = configuration.InsecureSkipVerify, + }); } } diff --git a/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN.Abp.Sms.Aliyun.csproj b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN.Abp.Sms.Aliyun.csproj index a2d642c68..aabe2f950 100644 --- a/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN.Abp.Sms.Aliyun.csproj +++ b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN.Abp.Sms.Aliyun.csproj @@ -21,6 +21,8 @@ + + diff --git a/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/AliyunSmsSender.cs b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/AliyunSmsSender.cs index 2e749fb0e..745422f5f 100644 --- a/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/AliyunSmsSender.cs +++ b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/AliyunSmsSender.cs @@ -1,14 +1,11 @@ -using Aliyun.Acs.Core; -using Aliyun.Acs.Core.Exceptions; -using Aliyun.Acs.Core.Http; -using LINGYUN.Abp.Aliyun; +using AlibabaCloud.SDK.Dypnsapi20170525.Models; +using AlibabaCloud.SDK.Dysmsapi20170525.Models; using LINGYUN.Abp.Aliyun.Features; using LINGYUN.Abp.Aliyun.Settings; using LINGYUN.Abp.Features.LimitValidation; using Microsoft.Extensions.DependencyInjection; using System; using System.Linq; -using System.Text; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.DependencyInjection; @@ -30,17 +27,20 @@ public class AliyunSmsSender : ISmsSender, IAliyunSmsVerifyCodeSender protected IJsonSerializer JsonSerializer { get; } protected ISettingProvider SettingProvider { get; } protected IServiceProvider ServiceProvider { get; } - protected IAcsClientFactory AcsClientFactory { get; } + protected IDypnsClientFactory DypnsClientFactory { get; } + protected IDysmsClientFactory DysmsClientFactory { get; } public AliyunSmsSender( IJsonSerializer jsonSerializer, ISettingProvider settingProvider, IServiceProvider serviceProvider, - IAcsClientFactory acsClientFactory) + IDypnsClientFactory dypnsClientFactory, + IDysmsClientFactory dysmsClientFactory) { JsonSerializer = jsonSerializer; SettingProvider = settingProvider; ServiceProvider = serviceProvider; - AcsClientFactory = acsClientFactory; + DypnsClientFactory = dypnsClientFactory; + DysmsClientFactory = dysmsClientFactory; } [RequiresLimitFeature( @@ -74,41 +74,23 @@ public class AliyunSmsSender : ISmsSender, IAliyunSmsVerifyCodeSender Check.NotNullOrWhiteSpace(action, AliyunSettingNames.Sms.ActionName); Check.NotNullOrWhiteSpace(version, AliyunSettingNames.Sms.Version); - var request = new CommonRequest - { - Method = MethodType.POST, - Domain = domain, - Action = action, - Version = version - }; + var request = new SendSmsRequest(); + await TryAddTemplateCodeAsync(request, smsMessage); await TryAddSignNameAsync(request, smsMessage); await TryAddSendPhoneAsync(request, smsMessage); - TryAddTemplateParam(request, smsMessage); - try + + var dysmsClient = await DysmsClientFactory.CreateAsync(); + var response = await dysmsClient.SendSmsAsync(request); + if (!string.Equals(response.Body.Code, "OK", StringComparison.CurrentCultureIgnoreCase)) { - var client = await AcsClientFactory.CreateAsync(); - var response = client.GetCommonResponse(request); - var responseContent = Encoding.Default.GetString(response.HttpResponse.Content); - var aliyunResponse = JsonSerializer.Deserialize(responseContent); - if (!aliyunResponse.IsSuccess()) + if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Sms.VisableErrorToClient)) { - if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Sms.VisableErrorToClient)) - { - throw new UserFriendlyException(aliyunResponse.Code, aliyunResponse.Message); - } - throw new AliyunSmsException(aliyunResponse.Code, $"Text message sending failed, code:{aliyunResponse.Code}, message:{aliyunResponse.Message}!"); + throw new UserFriendlyException(response.Body.Code, response.Body.Message); } - } - catch(ServerException se) - { - throw new AliyunSmsException(se.ErrorCode, $"Sending text messages to aliyun server is abnormal,type: {se.ErrorType}, error: {se.ErrorMessage}"); - } - catch(ClientException ce) - { - throw new AliyunSmsException(ce.ErrorCode, $"A client exception occurred in sending SMS messages,type: {ce.ErrorType}, error: {ce.ErrorMessage}"); + throw new AliyunSmsException(response.Body.Code, $"Text message sending failed, code:{response.Body.Code}, message:{response.Body.Message}!"); } } @@ -132,75 +114,58 @@ public class AliyunSmsSender : ISmsSender, IAliyunSmsVerifyCodeSender Check.NotNullOrWhiteSpace(signName, AliyunSettingNames.SmsVerifyCode.DefaultSignName); Check.NotNullOrWhiteSpace(templateCode, AliyunSettingNames.SmsVerifyCode.DefaultTemplateCode); - var request = new CommonRequest + var dypnsClient = await DypnsClientFactory.CreateAsync(); + + var request = new SendSmsVerifyCodeRequest { - Domain = domain, - Version = version, - Product = "Dypnsapi", - Method = MethodType.POST, - Action = "SendSmsVerifyCode", + PhoneNumber = message.PhoneNumber, + SignName = signName, + TemplateCode = templateCode, + TemplateParam = JsonSerializer.Serialize(message.TemplateParam), }; - request.AddBodyParameters("PhoneNumber", message.PhoneNumber); - request.AddBodyParameters("SignName", signName); - request.AddBodyParameters("TemplateCode", templateCode); - request.AddBodyParameters("TemplateParam", JsonSerializer.Serialize(message.TemplateParam)); - try + var response = await dypnsClient.SendSmsVerifyCodeAsync(request); + if (response.Body.Success == false) { - var client = await AcsClientFactory.CreateAsync(); - var response = client.GetCommonResponse(request); - var responseContent = Encoding.Default.GetString(response.HttpResponse.Content); - var aliyunResponse = JsonSerializer.Deserialize(responseContent); - if (!aliyunResponse.Success) + if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Sms.VisableErrorToClient)) { - if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Sms.VisableErrorToClient)) - { - throw new UserFriendlyException(aliyunResponse.Code, aliyunResponse.Message); - } - throw new AliyunSmsException(aliyunResponse.Code, $"Text message sending failed, code:{aliyunResponse.Code}, message:{aliyunResponse.Message}!"); + throw new UserFriendlyException(response.Body.Code, response.Body.Message); } - } - catch (ServerException se) - { - throw new AliyunSmsException(se.ErrorCode, $"Sending text messages to aliyun server is abnormal,type: {se.ErrorType}, error: {se.ErrorMessage}"); - } - catch (ClientException ce) - { - throw new AliyunSmsException(ce.ErrorCode, $"A client exception occurred in sending SMS messages,type: {ce.ErrorType}, error: {ce.ErrorMessage}"); + throw new AliyunSmsException(response.Body.Code, $"Text message sending failed, code:{response.Body.Code}, message:{response.Body.Message}!"); } } - private async Task TryAddTemplateCodeAsync(CommonRequest request, SmsMessage smsMessage) + private async Task TryAddTemplateCodeAsync(SendSmsRequest request, SmsMessage smsMessage) { - if (smsMessage.Properties.TryGetValue("TemplateCode", out object template) && template != null) + if (smsMessage.Properties.TryGetValue("TemplateCode", out var template) && template != null) { - request.AddQueryParameters("TemplateCode", template.ToString()); + request.TemplateCode = template.ToString(); smsMessage.Properties.Remove("TemplateCode"); } else { var defaultTemplateCode = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Sms.DefaultTemplateCode); Check.NotNullOrWhiteSpace(defaultTemplateCode, "TemplateCode"); - request.AddQueryParameters("TemplateCode", defaultTemplateCode); + request.TemplateCode = defaultTemplateCode; } } - private async Task TryAddSignNameAsync(CommonRequest request, SmsMessage smsMessage) + private async Task TryAddSignNameAsync(SendSmsRequest request, SmsMessage smsMessage) { - if (smsMessage.Properties.TryGetValue("SignName", out object signName) && signName != null) + if (smsMessage.Properties.TryGetValue("SignName", out var signName) && signName != null) { - request.AddQueryParameters("SignName", signName.ToString()); + request.SignName = signName.ToString(); smsMessage.Properties.Remove("SignName"); } else { var defaultSignName = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Sms.DefaultSignName); Check.NotNullOrWhiteSpace(defaultSignName, "SignName"); - request.AddQueryParameters("SignName", defaultSignName); + request.SignName = defaultSignName; } } - private async Task TryAddSendPhoneAsync(CommonRequest request, SmsMessage smsMessage) + private async Task TryAddSendPhoneAsync(SendSmsRequest request, SmsMessage smsMessage) { if (smsMessage.PhoneNumber.IsNullOrWhiteSpace()) { @@ -210,20 +175,20 @@ public class AliyunSmsSender : ISmsSender, IAliyunSmsVerifyCodeSender defaultPhoneNumber, AliyunSettingNames.Sms.DefaultPhoneNumber, maxLength: 11, minLength: 11); - request.AddQueryParameters("PhoneNumbers", defaultPhoneNumber); + request.PhoneNumbers = defaultPhoneNumber; } else { - request.AddQueryParameters("PhoneNumbers", smsMessage.PhoneNumber); + request.PhoneNumbers = smsMessage.PhoneNumber; } } - private void TryAddTemplateParam(CommonRequest request, SmsMessage smsMessage) + private void TryAddTemplateParam(SendSmsRequest request, SmsMessage smsMessage) { if (smsMessage.Properties.Any()) { var queryParamJson = JsonSerializer.Serialize(smsMessage.Properties); - request.AddQueryParameters("TemplateParam", queryParamJson); + request.TemplateParam = queryParamJson; } } } diff --git a/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/DypnsClientFactory.cs b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/DypnsClientFactory.cs new file mode 100644 index 000000000..3009b0f4e --- /dev/null +++ b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/DypnsClientFactory.cs @@ -0,0 +1,41 @@ +using AlibabaCloud.SDK.Dypnsapi20170525; +using LINGYUN.Abp.Aliyun; +using System; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Settings; + +namespace LINGYUN.Abp.Sms.Aliyun; + +public class DypnsClientFactory : AliyunClientFactory, IDypnsClientFactory, ITransientDependency +{ + public DypnsClientFactory( + ISettingProvider settingProvider, + IDistributedCache cache) + : base(settingProvider, cache) + { + } + + protected override Client GetClient(string regionId, string accessKeyId, string accessKeySecret) + { + return new Client( + new AlibabaCloud.OpenApiClient.Models.Config + { + RegionId = regionId, + AccessKeyId = accessKeyId, + AccessKeySecret = accessKeySecret, + }); + } + + protected override Client GetSecurityTokenClient(string regionId, string accessKeyId, string accessKeySecret, string securityToken, DateTime? expiration = null) + { + return new Client( + new AlibabaCloud.OpenApiClient.Models.Config + { + RegionId = regionId, + AccessKeyId = accessKeyId, + AccessKeySecret = accessKeySecret, + SecurityToken = securityToken, + }); + } +} diff --git a/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/DysmsClientFactory.cs b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/DysmsClientFactory.cs new file mode 100644 index 000000000..66aaff90e --- /dev/null +++ b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/DysmsClientFactory.cs @@ -0,0 +1,38 @@ +using AlibabaCloud.SDK.Dysmsapi20170525; +using LINGYUN.Abp.Aliyun; +using System; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Settings; + +namespace LINGYUN.Abp.Sms.Aliyun; + +public class DysmsClientFactory : AliyunClientFactory, IDysmsClientFactory, ITransientDependency +{ + public DysmsClientFactory(ISettingProvider settingProvider, IDistributedCache cache) : base(settingProvider, cache) + { + } + + protected override Client GetClient(string regionId, string accessKeyId, string accessKeySecret) + { + return new Client( + new AlibabaCloud.OpenApiClient.Models.Config + { + RegionId = regionId, + AccessKeyId = accessKeyId, + AccessKeySecret = accessKeySecret, + }); + } + + protected override Client GetSecurityTokenClient(string regionId, string accessKeyId, string accessKeySecret, string securityToken, DateTime? expiration = null) + { + return new Client( + new AlibabaCloud.OpenApiClient.Models.Config + { + RegionId = regionId, + AccessKeyId = accessKeyId, + AccessKeySecret = accessKeySecret, + SecurityToken = securityToken, + }); + } +} diff --git a/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/IDypnsClientFactory.cs b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/IDypnsClientFactory.cs new file mode 100644 index 000000000..21364c171 --- /dev/null +++ b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/IDypnsClientFactory.cs @@ -0,0 +1,13 @@ +using AlibabaCloud.SDK.Dypnsapi20170525; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Sms.Aliyun; + +public interface IDypnsClientFactory +{ + /// + /// 构建短信认证客户端 + /// + /// + Task CreateAsync(); +} diff --git a/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/IDysmsClientFactory.cs b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/IDysmsClientFactory.cs new file mode 100644 index 000000000..b368f5066 --- /dev/null +++ b/aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/IDysmsClientFactory.cs @@ -0,0 +1,13 @@ +using AlibabaCloud.SDK.Dysmsapi20170525; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Sms.Aliyun; + +public interface IDysmsClientFactory +{ + /// + /// 构建短信客户端 + /// + /// + Task CreateAsync(); +}