Browse Source

feat(aliyun): Optimize the integration module of Alibaba Cloud

- Use Alibaba Cloud v2 SDK
pull/1489/head
colin 4 days ago
parent
commit
6d725513a8
  1. 4
      Directory.Packages.props
  2. 2
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj
  3. 34
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AcsClientFactory.cs
  4. 11
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunBasicSessionCredentialsCacheItem.cs
  5. 97
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunClientFactory.cs
  6. 14
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/IAcsClientFactory.cs
  7. 2
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Settings/AliyunSettingProvider.cs
  8. 2
      aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN.Abp.BlobStoring.Aliyun.csproj
  9. 109
      aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs
  10. 19
      aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfiguration.cs
  11. 8
      aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfigurationNames.cs
  12. 6
      aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/IOssClientFactory.cs
  13. 86
      aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/OssClientFactory.cs
  14. 2
      aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN.Abp.Sms.Aliyun.csproj
  15. 119
      aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/AliyunSmsSender.cs
  16. 41
      aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/DypnsClientFactory.cs
  17. 38
      aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/DysmsClientFactory.cs
  18. 13
      aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/IDypnsClientFactory.cs
  19. 13
      aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN/Abp/Sms/Aliyun/IDysmsClientFactory.cs

4
Directory.Packages.props

@ -333,6 +333,10 @@
<PackageVersion Include="Microsoft.IdentityModel.Tokens" Version="8.14.0" />
<PackageVersion Include="aliyun-net-sdk-core" Version="1.6.2" />
<PackageVersion Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" />
<PackageVersion Include="AlibabaCloud.SDK.Dypnsapi20170525" Version="2.0.0" />
<PackageVersion Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="4.3.1" />
<PackageVersion Include="AlibabaCloud.SDK.Sts20150401" Version="1.2.0" />
<PackageVersion Include="AlibabaCloud.OSS.V2" Version="0.1.2" />
<PackageVersion Include="AgileConfig.Client" Version="1.8.0" />
<PackageVersion Include="CommonMark.NET" Version="0.15.1" />
<PackageVersion Include="DocumentFormat.OpenXml" Version="3.5.1" />

2
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj

@ -25,7 +25,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="aliyun-net-sdk-core" />
<PackageReference Include="AlibabaCloud.SDK.Sts20150401" />
<PackageReference Include="Volo.Abp.Caching" />
<PackageReference Include="Volo.Abp.Features" />
<PackageReference Include="Volo.Abp.Localization" />

34
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AcsClientFactory.cs

@ -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<IAcsClient>, IAcsClientFactory, ITransientDependency
{
public AcsClientFactory(
ISettingProvider settingProvider,
IDistributedCache<AliyunBasicSessionCredentialsCacheItem> 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);
}
}

11
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;
}
}

97
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<TClient>
{
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<AliyunBasicSessionCredentialsCacheItem> 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<TClient>
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<TClient, TConfiguration> : 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);
}

14
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/IAcsClientFactory.cs

@ -1,14 +0,0 @@
using Aliyun.Acs.Core;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Aliyun;
public interface IAcsClientFactory
{
/// <summary>
/// 构造一个通用的Acs客户端调用
/// 通过CommonRequest调用可以不需要集成其他SDK包
/// </summary>
/// <returns></returns>
Task<IAcsClient> CreateAsync();
}

2
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

2
aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN.Abp.BlobStoring.Aliyun.csproj

@ -15,7 +15,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aliyun.OSS.SDK.NetCore" />
<PackageReference Include="AlibabaCloud.OSS.V2" />
<PackageReference Include="Microsoft.Extensions.Http" />
<PackageReference Include="Volo.Abp.BlobStoring" />
</ItemGroup>

109
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<IOss> GetOssClientAsync(BlobProviderArgs args)
protected async virtual Task<Client> GetOssClientAsync(BlobProviderArgs args)
{
var ossClient = await OssClientFactory.CreateAsync();
return ossClient;
return await OssClientFactory.CreateAsync();
}
protected async virtual Task CreateBucketIfNotExists(IOss ossClient, BlobProviderArgs args, IList<string> 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<bool> BlobExistsAsync(IOss ossClient, BlobProviderArgs args, string blobName)
private async Task<bool> 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<bool> BucketExistsAsync(IOss ossClient, BlobProviderArgs args)
private async Task<bool> 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)

19
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);
}
/// <summary>
/// 跳过服务器证书验证
/// </summary>
public bool InsecureSkipVerify {
get => _containerConfiguration.GetConfigurationOrDefault(AliyunBlobProviderConfigurationNames.InsecureSkipVerify, false);
set => _containerConfiguration.SetConfiguration(AliyunBlobProviderConfigurationNames.InsecureSkipVerify, value);
}
/// <summary>
/// 命名空间不存在是否创建
/// </summary>
public bool CreateBucketIfNotExists
@ -22,11 +30,18 @@ public class AliyunBlobProviderConfiguration
set => _containerConfiguration.SetConfiguration(AliyunBlobProviderConfigurationNames.CreateBucketIfNotExists, value);
}
/// <summary>
/// 创建命名空间时的Acl
/// </summary>
public BucketAclType? CreateBucketAcl {
get => _containerConfiguration.GetConfigurationOrDefault<BucketAclType?>(AliyunBlobProviderConfigurationNames.CreateBucketAcl);
set => _containerConfiguration.SetConfiguration(AliyunBlobProviderConfigurationNames.CreateBucketAcl, value);
}
/// <summary>
/// 创建命名空间时防盗链列表
/// </summary>
public List<string> CreateBucketReferer
{
get => _containerConfiguration.GetConfiguration<List<string>>(AliyunBlobProviderConfigurationNames.CreateBucketReferer);
get => _containerConfiguration.GetConfigurationOrDefault(AliyunBlobProviderConfigurationNames.CreateBucketReferer, new List<string>());
set
{
if (value == null)

8
aspnet-core/framework/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProviderConfigurationNames.cs

@ -11,6 +11,10 @@ public static class AliyunBlobProviderConfigurationNames
/// </summary>
public const string BucketName = "Aliyun:OSS:BucketName";
/// <summary>
/// 跳过服务器证书验证
/// </summary>
public const string InsecureSkipVerify = "Aliyun:OSS:InsecureSkipVerify";
/// <summary>
/// 命名空间不存在是否创建
/// </summary>
public const string CreateBucketIfNotExists = "Aliyun:OSS:CreateBucketIfNotExists";
@ -19,6 +23,10 @@ public static class AliyunBlobProviderConfigurationNames
/// </summary>
public const string CreateBucketReferer = "Aliyun:OSS:CreateBucketReferer";
/// <summary>
/// 创建命名空间时的Acl
/// </summary>
public const string CreateBucketAcl = "Aliyun:OSS:CreateBucketAcl";
/// <summary>
/// 生成预签名Uri的过期时间(s)
/// </summary>
public const string PresignedGetExpirySeconds = "Aliyun:OSS:PresignedGetExpirySeconds";

6
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客户端
/// </summary>
/// <returns></returns>
Task<IOss> CreateAsync();
Task<Client> CreateAsync();
/// <summary>
/// 构建Oss客户端
/// </summary>
/// <param name="configuration"></param>
/// <returns></returns>
Task<IOss> CreateAsync(AliyunBlobProviderConfiguration configuration);
Task<Client> CreateAsync(AliyunBlobProviderConfiguration configuration);
}

86
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<IOss, AliyunBlobProviderConfiguration>, IOssClientFactory, ITransientDependency
public class OssClientFactory : AliyunClientFactory<Client, AliyunBlobProviderConfiguration>, IOssClientFactory, ITransientDependency
{
public OssClientFactory(
ISettingProvider settingProvider,
@ -22,12 +24,22 @@ public class OssClientFactory : AliyunClientFactory<IOss, AliyunBlobProviderConf
/// <param name="accessKeyId"></param>
/// <param name="accessKeySecret"></param>
/// <returns></returns>
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);
}
/// <summary>
@ -38,12 +50,18 @@ public class OssClientFactory : AliyunClientFactory<IOss, AliyunBlobProviderConf
/// <param name="accessKeyId"></param>
/// <param name="accessKeySecret"></param>
/// <returns></returns>
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,
});
}
/// <summary>
@ -54,13 +72,22 @@ public class OssClientFactory : AliyunClientFactory<IOss, AliyunBlobProviderConf
/// <param name="accessKeySecret"></param>
/// <param name="securityToken"></param>
/// <returns></returns>
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);
}),
});
}
/// <summary>
/// 通过用户安全令牌构建Oss客户端
@ -71,12 +98,23 @@ public class OssClientFactory : AliyunClientFactory<IOss, AliyunBlobProviderConf
/// <param name="accessKeySecret"></param>
/// <param name="securityToken"></param>
/// <returns></returns>
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,
});
}
}

2
aspnet-core/framework/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN.Abp.Sms.Aliyun.csproj

@ -21,6 +21,8 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Sms" />
<PackageReference Include="AlibabaCloud.SDK.Dypnsapi20170525" />
<PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" />
</ItemGroup>
<ItemGroup>

119
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<AliyunSmsResponse>(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<AliyunSmsVerifyCodeResponse>(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;
}
}
}

41
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<Client>, IDypnsClientFactory, ITransientDependency
{
public DypnsClientFactory(
ISettingProvider settingProvider,
IDistributedCache<AliyunBasicSessionCredentialsCacheItem> 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,
});
}
}

38
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<Client>, IDysmsClientFactory, ITransientDependency
{
public DysmsClientFactory(ISettingProvider settingProvider, IDistributedCache<AliyunBasicSessionCredentialsCacheItem> 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,
});
}
}

13
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
{
/// <summary>
/// 构建短信认证客户端
/// </summary>
/// <returns></returns>
Task<Client> CreateAsync();
}

13
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
{
/// <summary>
/// 构建短信客户端
/// </summary>
/// <returns></returns>
Task<Client> CreateAsync();
}
Loading…
Cancel
Save