xf 1 éve
szülő
commit
c0c234623c

+ 20 - 3
src/FileStorage.Host/Controllers/FileController.cs

@@ -1,5 +1,6 @@
 using FileStorage.Repository.SqlSugar;
 using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.StaticFiles;
 using Microsoft.Extensions.Options;
@@ -42,7 +43,7 @@ namespace FileStorage.Host.Controllers
         [HttpGet("getfileurl/{id}")]
         public async Task<IActionResult> GetFileUrl(string id)
         {
-            var uri = await _fileStorage.GetFileUrlAsync(id);
+            var uri = await _fileStorage.GetFileUrlAsync(id,_sessionContext.ClientId ?? string.Empty);
             return Ok(new { Uri = uri });
         }
 
@@ -50,7 +51,7 @@ namespace FileStorage.Host.Controllers
         [HttpGet("downloadfile/{id}")]
         public async Task<IActionResult> DownLoadFile(string id)
         {
-            var (stream, content, fileName) = _fileStorage.DownLoadFile(id);
+            var (stream, content, fileName) = _fileStorage.DownLoadFile(id,_sessionContext.ClientId ?? string.Empty);
             if (stream != null)
             {
                 return File(stream, content, fileName);
@@ -61,7 +62,7 @@ namespace FileStorage.Host.Controllers
         [HttpGet("delfile/{id}")]
         public async Task<bool> DelFile(string id)
         {
-            return await _fileStorage.DelFileAsync(id);
+            return await _fileStorage.DelFileAsync(id,_sessionContext.ClientId?? string.Empty);
         }
 
 
@@ -73,5 +74,21 @@ namespace FileStorage.Host.Controllers
             db.CodeFirst.InitTables<FileMetadata>();
             return Task.CompletedTask;
         }
+
+        /// <summary>
+        /// ·ÃÎÊÎļþ
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="expires"></param>
+        /// <param name="clientid"></param>
+        /// <param name="signature"></param>
+        /// <returns></returns>
+        [AllowAnonymous]
+        [HttpGet("files")]
+        public async Task Files(string id,string expires,string clientid,string signature)
+        {
+            var fullPath = await _fileStorage.GetFilePath(id,expires,clientid,signature);
+            await HttpContext.Response.SendFileAsync(fullPath);
+        }
     }
 }

+ 5 - 5
src/FileStorage.Host/StartupExtensions.cs

@@ -103,11 +103,11 @@ internal static class StartupExtensions
         {
             Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(), "uploads"));
         };
-        app.UseStaticFiles(new StaticFileOptions
-        {
-            FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "uploads")),
-            RequestPath = new PathString("/uploads")
-        });
+        //app.UseStaticFiles(new StaticFileOptions
+        //{
+        //    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "Uploads")),
+        //    RequestPath = new PathString("/Uploads")
+        //});
 
         app.MapControllers();
 

BIN
src/FileStorage.Host/Uploads/hotline_admin/20230725/a591d84e6b144af3b351ff7405f94818.png


+ 40 - 10
src/FileStorage/DefaultFileStorage.cs

@@ -1,6 +1,8 @@
-using Microsoft.AspNetCore.StaticFiles;
+using FileStorage.Extensions;
+using Microsoft.AspNetCore.StaticFiles;
 using Microsoft.Extensions.Options;
 using XF.Domain.Dependency;
+using XF.Domain.Exceptions;
 
 namespace FileStorage;
 
@@ -57,19 +59,23 @@ public class DefaultFileStorage : IFileStorage, IScopeDependency
         return null;
     }
 
-    public async Task<Uri> GetFileUrlAsync(string id)
+    public async Task<Uri> GetFileUrlAsync(string id,string clientId)
     {
-        var fileMetadata = await _fileMetadataRepository.GetAsync(id);
+        var fileMetadata = await _fileMetadataRepository.GetAsync(x=>x.Id== id && x.Client== clientId);
         if (fileMetadata != null)
         {
-            return new Uri(_fileUploadOptions.Value.Local.VisDomain+fileMetadata.Path);
+            long sTime = (long)(DateTime.Now.AddHours(1).ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
+            string encryptText = clientId + "|" + sTime + "|" + id;
+            var signatureText = DESExtensions.Encrypt(encryptText);
+            return new Uri(_fileUploadOptions.Value.Local.VisDomain + "file/files?id=" + id + "&expires=" + sTime + "&clientid=" + clientId + "&signature=" + signatureText);
+            //return new Uri(_fileUploadOptions.Value.Local.VisDomain+fileMetadata.Path);
         }
-        return new Uri("");
+        throw new UserFriendlyException("无权限访问");
     }
 
-    public (Stream stream, string contentType,string fileName) DownLoadFile(string id)
+    public (Stream stream, string contentType,string fileName) DownLoadFile(string id,string clientId)
     {
-        var fileMetadata = _fileMetadataRepository.Get(id);
+        var fileMetadata = _fileMetadataRepository.Get(x=>x.Id == id && x.Client == clientId);
         if (fileMetadata!=null)
         {
             string filePath = Path.Combine(Directory.GetCurrentDirectory(), fileMetadata.Path);
@@ -77,12 +83,12 @@ public class DefaultFileStorage : IFileStorage, IScopeDependency
             var stream = File.OpenRead(filePath);
             return (stream,contentType,fileMetadata.FileName);
         }
-        return (null,"","");
+        throw new UserFriendlyException("无权限访问");
     }
 
-    public async Task<bool> DelFileAsync(string id)
+    public async Task<bool> DelFileAsync(string id, string clientId)
     {
-        var fileMetadata = await _fileMetadataRepository.GetAsync(id);
+        var fileMetadata = await _fileMetadataRepository.GetAsync(x=>x.Id == id && x.Client == clientId);
         if (fileMetadata!=null)
         {
             string filePath = Path.Combine(Directory.GetCurrentDirectory(), fileMetadata.Path);
@@ -93,6 +99,30 @@ public class DefaultFileStorage : IFileStorage, IScopeDependency
         return false;
     }
 
+    public async Task<string> GetFilePath(string id, string expires, string clientId, string signature)
+    {
+        string decryptText = DESExtensions.Decrypt(signature);
+        if (!string.IsNullOrEmpty(decryptText))
+        {
+            string[] paramData = decryptText.Split('|');
+            
+            if (id != paramData[2] || clientId != paramData[0] || expires != paramData[1])
+                throw UserFriendlyException.SameMessage("参数不合法");
+
+            if (long.Parse(paramData[1]) < ((long)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds))
+                throw UserFriendlyException.SameMessage("链接已过期");
+
+            var fileMetadata = await _fileMetadataRepository.GetAsync(x => x.Id == id && x.Client == clientId);
+            if (fileMetadata == null)
+                throw UserFriendlyException.SameMessage("无权限访问");
+
+            return GetFullPath(fileMetadata.Path);
+        }
+        throw UserFriendlyException.SameMessage("无权限访问");
+    }
+
+
+
     private string TaskGetFileContentTypeAsync(string fileName)
     {
         string suffix = Path.GetExtension(fileName);

+ 65 - 0
src/FileStorage/Extensions/DESExtensions.cs

@@ -0,0 +1,65 @@
+using Microsoft.AspNetCore.DataProtection.KeyManagement;
+using System.Security.Cryptography;
+using System.Text;
+using static System.Net.Mime.MediaTypeNames;
+
+namespace FileStorage.Extensions
+{
+    public static class DESExtensions
+    {
+        private const string key = "fwayfway";
+
+        /// <summary>
+        /// 加密
+        /// </summary>
+        /// <param name="text"></param>
+        /// <returns></returns>
+        public static string Encrypt(string text)
+        {
+
+            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
+            byte[] inputByteArray;
+            inputByteArray = Encoding.Default.GetBytes(text);
+            des.Key = ASCIIEncoding.ASCII.GetBytes(key);
+            des.IV = ASCIIEncoding.ASCII.GetBytes(key);
+            System.IO.MemoryStream ms = new System.IO.MemoryStream();
+            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
+            cs.Write(inputByteArray, 0, inputByteArray.Length);
+            cs.FlushFinalBlock();
+            StringBuilder ret = new StringBuilder();
+            foreach (byte b in ms.ToArray())
+            {
+                ret.AppendFormat("{0:X2}", b);
+            }
+            return ret.ToString();
+
+        }
+
+        /// <summary>
+        /// 解密
+        /// </summary>
+        /// <param name="text"></param>
+        /// <returns></returns>
+        public static string Decrypt(string text)
+        {
+            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
+            int len;
+            len = text.Length / 2;
+            byte[] inputByteArray = new byte[len];
+            int x, i;
+            for (x = 0; x < len; x++)
+            {
+                i = Convert.ToInt32(text.Substring(x * 2, 2), 16);
+                inputByteArray[x] = (byte)i;
+            }
+            des.Key = ASCIIEncoding.ASCII.GetBytes(key);
+            des.IV = ASCIIEncoding.ASCII.GetBytes(key);
+            System.IO.MemoryStream ms = new System.IO.MemoryStream();
+            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
+            cs.Write(inputByteArray, 0, inputByteArray.Length);
+            cs.FlushFinalBlock();
+            return Encoding.Default.GetString(ms.ToArray());
+            
+        }
+    }
+}

+ 5 - 3
src/FileStorage/IFileStorage.cs

@@ -5,10 +5,12 @@
 
         FileMetadata Upload(string fileName, long length, string extraInfo, Stream fileData, string client);
 
-        Task<Uri> GetFileUrlAsync(string id);
+        Task<Uri> GetFileUrlAsync(string id, string clientId);
 
-        (Stream stream, string contentType,string fileName) DownLoadFile(string id);
+        (Stream stream, string contentType,string fileName) DownLoadFile(string id, string clientId);
 
-        Task<bool> DelFileAsync(string id);
+        Task<bool> DelFileAsync(string id, string clientId);
+
+        Task<string> GetFilePath(string id, string expires, string clientId, string signature);
     }
 }