From 092a9c2dc6f93fed92cba44c205bf47e421cd2c9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 9 Sep 2024 14:58:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E4=B8=8A=E4=BC=A0=E4=B9=9F?= =?UTF-8?q?=E7=94=A8=E4=B8=B4=E6=97=B6token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ExtraController.cs | 100 +------------ IRaCIS.Core.API/IRaCIS.Core.API.csproj | 3 +- IRaCIS.Core.Application/Helper/OSSService.cs | 131 ++++++++++++++++-- .../IRaCIS.Core.Application.csproj | 2 + 4 files changed, 130 insertions(+), 106 deletions(-) diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 59076ec3e..000f81c25 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -221,9 +221,9 @@ namespace IRaCIS.Api.Controllers if (_verifyConfig.CurrentValue.OpenLoginMFA) { - - + + //MFA 发送邮件 @@ -307,102 +307,14 @@ namespace IRaCIS.Api.Controllers } [HttpGet("user/GetObjectStoreToken")] - public async Task GetObjectStoreTokenAsync([FromServices] IOptionsMonitor options) + public async Task GetObjectStoreTokenAsync([FromServices] IOptionsMonitor options, [FromServices] IOSSService _oSSService) { - var serviceOption = options.CurrentValue; - if (Enum.TryParse(serviceOption.ObjectStoreUse, out var parsedEnum) && parsedEnum == ObjectStoreUse.AliyunOSS) - { + var result = await _oSSService.GetObjectStoreTempToken(); - var ossOptions = serviceOption.AliyunOSS; + result.AWS =await GetAWSTemToken(options.CurrentValue); - var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config() - { - AccessKeyId = ossOptions.AccessKeyId, - AccessKeySecret = ossOptions.AccessKeySecret, - //AccessKeyId = "LTAI5tJV76pYX5yPg1N9QVE8", - //AccessKeySecret = "roRNLa9YG1of4pYruJGCNKBXEWTAWa", - - Endpoint = "sts.cn-hangzhou.aliyuncs.com" - }); - - var assumeRoleRequest = new AlibabaCloud.SDK.Sts20150401.Models.AssumeRoleRequest(); - // 将设置为自定义的会话名称,例如oss-role-session。 - assumeRoleRequest.RoleSessionName = $"session-name-{NewId.NextGuid()}"; - // 将替换为拥有上传文件到指定OSS Bucket权限的RAM角色的ARN。 - assumeRoleRequest.RoleArn = ossOptions.RoleArn; - //assumeRoleRequest.RoleArn = "acs:ram::1899121822495495:role/webdirect"; - assumeRoleRequest.DurationSeconds = ossOptions.DurationSeconds; - var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions(); - var response = client.AssumeRoleWithOptions(assumeRoleRequest, runtime); - var credentials = response.Body.Credentials; - - var tempToken = new AliyunOSSTempToken() - { - AccessKeyId = credentials.AccessKeyId, - AccessKeySecret = credentials.AccessKeySecret, - - //转为服务器时区,最后统一转为客户端时区 - Expiration = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(credentials.Expiration), TimeZoneInfo.Local), - SecurityToken = credentials.SecurityToken, - - - Region = ossOptions.Region, - BucketName = ossOptions.BucketName, - EndPoint = ossOptions.EndPoint, - ViewEndpoint = ossOptions.ViewEndpoint, - - }; - - var awstempToken = await GetAWSTemToken(serviceOption); - - return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, AliyunOSS = tempToken,AWS= awstempToken }); - - - } - else if (Enum.TryParse(serviceOption.ObjectStoreUse, out var parsedValue) && parsedValue == ObjectStoreUse.MinIO) - { - return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO}); - } - else - { - var awsOptions = serviceOption.AWS; - - //aws 临时凭证 - // 创建 STS 客户端 - var stsClient = new AmazonSecurityTokenServiceClient(awsOptions.AccessKeyId, awsOptions.SecretAccessKey); - - // 使用 AssumeRole 请求临时凭证 - var assumeRoleRequest = new AssumeRoleRequest - { - - RoleArn = awsOptions.RoleArn, // 角色 ARN - RoleSessionName = $"session-name-{NewId.NextGuid()}", - DurationSeconds = awsOptions.DurationSeconds // 临时凭证有效期 - }; - - var assumeRoleResponse = await stsClient.AssumeRoleAsync(assumeRoleRequest); - - var credentials = assumeRoleResponse.Credentials; - - var tempToken = new AWSTempToken() - { - AccessKeyId = credentials.AccessKeyId, - SecretAccessKey = credentials.SecretAccessKey, - SessionToken= credentials.SessionToken, - Expiration=credentials.Expiration, - Region=awsOptions.Region, - - BucketName = awsOptions.BucketName, - EndPoint = awsOptions.EndPoint, - ViewEndpoint = awsOptions.ViewEndpoint, - - }; - - - - return ResponseOutput.Ok(new ObjectStoreDTO() { ObjectStoreUse = serviceOption.ObjectStoreUse, MinIO = serviceOption.MinIO, AWS = tempToken }); - } + return ResponseOutput.Ok(result); } diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index 2de032f41..d73c5fbc1 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -61,10 +61,9 @@ - - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/IRaCIS.Core.Application/Helper/OSSService.cs b/IRaCIS.Core.Application/Helper/OSSService.cs index 261594914..9c7e96872 100644 --- a/IRaCIS.Core.Application/Helper/OSSService.cs +++ b/IRaCIS.Core.Application/Helper/OSSService.cs @@ -24,6 +24,10 @@ using Amazon.Runtime; using Amazon.S3; using Amazon.S3.Model; using MassTransit.Caching.Internals; +using MassTransit; +using AlibabaCloud.SDK.Sts20150401; +using Amazon.SecurityToken; +using Amazon.SecurityToken.Model; namespace IRaCIS.Core.Application.Helper { @@ -158,6 +162,8 @@ namespace IRaCIS.Core.Application.Helper public Task GetSignedUrl(string ossRelativePath); public Task DeleteFromPrefix(string prefix); + + public Task GetObjectStoreTempToken(); } @@ -165,10 +171,16 @@ namespace IRaCIS.Core.Application.Helper { public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; } + private AliyunOSSTempToken AliyunOSSTempToken { get; set; } + + private AWSTempToken AWSTempToken { get; set; } + public OSSService(IOptionsMonitor options) { ObjectStoreServiceOptions = options.CurrentValue; + + GetObjectStoreTempToken().GetAwaiter().GetResult(); } /// @@ -198,7 +210,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); @@ -228,7 +240,7 @@ namespace IRaCIS.Core.Application.Helper var awsConfig = ObjectStoreServiceOptions.AWS; // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey); + var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config @@ -287,7 +299,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); // 上传文件 var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, localFilePath); @@ -314,7 +326,7 @@ namespace IRaCIS.Core.Application.Helper var awsConfig = ObjectStoreServiceOptions.AWS; // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey); + var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config @@ -355,7 +367,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); // 上传文件 var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath); @@ -389,7 +401,7 @@ namespace IRaCIS.Core.Application.Helper var awsConfig = ObjectStoreServiceOptions.AWS; // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey); + var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config @@ -438,7 +450,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); // 生成签名URL。 var req = new GeneratePresignedUriRequest(aliConfig.BucketName, ossRelativePath, SignHttpMethod.Get) @@ -482,7 +494,7 @@ namespace IRaCIS.Core.Application.Helper // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey); + var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config @@ -530,7 +542,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, aliConfig.AccessKeyId, aliConfig.AccessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken); try @@ -611,7 +623,7 @@ namespace IRaCIS.Core.Application.Helper // 提供awsAccessKeyId和awsSecretAccessKey构造凭证 - var credentials = new BasicAWSCredentials(awsConfig.AccessKeyId, awsConfig.SecretAccessKey); + var credentials = new BasicAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey); //提供awsEndPoint(域名)进行访问配置 var clientConfig = new AmazonS3Config @@ -659,6 +671,105 @@ namespace IRaCIS.Core.Application.Helper throw new BusinessValidationFailedException("未定义的存储介质类型"); } } + + + + + public async Task GetObjectStoreTempToken() + { + var ossOptions = ObjectStoreServiceOptions.AliyunOSS; + + if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") + { + var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config() + { + AccessKeyId = ossOptions.AccessKeyId, + AccessKeySecret = ossOptions.AccessKeySecret, + //AccessKeyId = "LTAI5tJV76pYX5yPg1N9QVE8", + //AccessKeySecret = "roRNLa9YG1of4pYruJGCNKBXEWTAWa", + + Endpoint = "sts.cn-hangzhou.aliyuncs.com" + }); + + var assumeRoleRequest = new AlibabaCloud.SDK.Sts20150401.Models.AssumeRoleRequest(); + // 将设置为自定义的会话名称,例如oss-role-session。 + assumeRoleRequest.RoleSessionName = $"session-name-{NewId.NextGuid()}"; + // 将替换为拥有上传文件到指定OSS Bucket权限的RAM角色的ARN。 + assumeRoleRequest.RoleArn = ossOptions.RoleArn; + //assumeRoleRequest.RoleArn = "acs:ram::1899121822495495:role/webdirect"; + assumeRoleRequest.DurationSeconds = ossOptions.DurationSeconds; + var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions(); + var response = client.AssumeRoleWithOptions(assumeRoleRequest, runtime); + var credentials = response.Body.Credentials; + + var tempToken = new AliyunOSSTempToken() + { + AccessKeyId = credentials.AccessKeyId, + AccessKeySecret = credentials.AccessKeySecret, + + //转为服务器时区,最后统一转为客户端时区 + Expiration = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(credentials.Expiration), TimeZoneInfo.Local), + SecurityToken = credentials.SecurityToken, + + + Region = ossOptions.Region, + BucketName = ossOptions.BucketName, + EndPoint = ossOptions.EndPoint, + ViewEndpoint = ossOptions.ViewEndpoint, + + }; + + AliyunOSSTempToken=tempToken; + + return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AliyunOSS = tempToken }; + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") + { + return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, MinIO = ObjectStoreServiceOptions.MinIO }; + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") + { + var awsOptions = ObjectStoreServiceOptions.AWS; + + //aws 临时凭证 + // 创建 STS 客户端 + var stsClient = new AmazonSecurityTokenServiceClient(awsOptions.AccessKeyId, awsOptions.SecretAccessKey); + + // 使用 AssumeRole 请求临时凭证 + var assumeRoleRequest = new AssumeRoleRequest + { + + RoleArn = awsOptions.RoleArn, // 角色 ARN + RoleSessionName = $"session-name-{NewId.NextGuid()}", + DurationSeconds = awsOptions.DurationSeconds // 临时凭证有效期 + }; + + var assumeRoleResponse = await stsClient.AssumeRoleAsync(assumeRoleRequest); + + var credentials = assumeRoleResponse.Credentials; + + var tempToken = new AWSTempToken() + { + AccessKeyId = credentials.AccessKeyId, + SecretAccessKey = credentials.SecretAccessKey, + SessionToken = credentials.SessionToken, + Expiration = credentials.Expiration, + Region = awsOptions.Region, + BucketName = awsOptions.BucketName, + EndPoint = awsOptions.EndPoint, + ViewEndpoint = awsOptions.ViewEndpoint, + + }; + + AWSTempToken = tempToken; + return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AWS = tempToken }; + } + else + { + throw new BusinessValidationFailedException("未定义的存储介质类型"); + } + } + } diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index 1c751043f..0f1672ecf 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -58,6 +58,8 @@ + +