Explorar el Código

😎调整上传文件类型验证相关代码

zuohuaijun hace 2 años
padre
commit
383517e595

+ 8 - 4
Admin.NET/Admin.NET.Core/Service/File/SysFileService.cs

@@ -23,6 +23,7 @@ public class SysFileService : IDynamicApiController, ITransient
     private readonly OSSProviderOptions _OSSProviderOptions;
     private readonly UploadOptions _uploadOptions;
     private readonly IOSSService _OSSService;
+    private readonly string _imageType = ".jpg.png.bmp.gif.tif";
 
     public SysFileService(UserManager userManager,
         SqlSugarRepository<SysFile> sysFileRep,
@@ -241,7 +242,7 @@ public class SysFileService : IDynamicApiController, ITransient
     /// </summary>
     /// <param name="file">文件</param>
     /// <param name="savePath">路径</param>
-    /// <param name="allowSuffix">允许的格式,比如 .jpg.png.gif.tif.bmp </param>
+    /// <param name="allowSuffix">允许格式:.jpg.png.gif.tif.bmp</param>
     /// <returns></returns>
     private async Task<SysFile> HandleUploadFile(IFormFile file, string savePath, string allowSuffix = "")
     {
@@ -278,12 +279,15 @@ public class SysFileService : IDynamicApiController, ITransient
             });
         }
 
+        // 验证文件类型
         if (!_uploadOptions.ContentType.Contains(file.ContentType))
             throw Oops.Oh(ErrorCodeEnum.D8001);
 
+        // 验证文件大小
         if (sizeKb > _uploadOptions.MaxSize)
             throw Oops.Oh(ErrorCodeEnum.D8002);
 
+        // 获取文件后缀
         var suffix = Path.GetExtension(file.FileName).ToLower(); // 后缀
         if (string.IsNullOrWhiteSpace(suffix))
         {
@@ -296,7 +300,7 @@ public class SysFileService : IDynamicApiController, ITransient
         if (string.IsNullOrWhiteSpace(suffix))
             throw Oops.Oh(ErrorCodeEnum.D8003);
 
-        //增强安全,防止客户端伪造文件
+        // 防止客户端伪造文件类型
         if (!string.IsNullOrWhiteSpace(allowSuffix) && !allowSuffix.Contains(suffix))
             throw Oops.Oh(ErrorCodeEnum.D8003);
         if (!VerifyFileExtensionName.IsSameType(file.OpenReadStream(), suffix))
@@ -391,7 +395,7 @@ public class SysFileService : IDynamicApiController, ITransient
     [DisplayName("上传头像")]
     public async Task<SysFile> UploadAvatar([Required] IFormFile file)
     {
-        var sysFile = await HandleUploadFile(file, "Upload/Avatar", ".jpg.png.gif.tif.bmp");
+        var sysFile = await HandleUploadFile(file, "Upload/Avatar", _imageType);
 
         var sysUserRep = _sysFileRep.ChangeRepository<SqlSugarRepository<SysUser>>();
         var user = sysUserRep.GetFirst(u => u.Id == _userManager.UserId);
@@ -413,7 +417,7 @@ public class SysFileService : IDynamicApiController, ITransient
     [DisplayName("上传电子签名")]
     public async Task<SysFile> UploadSignature([Required] IFormFile file)
     {
-        var sysFile = await HandleUploadFile(file, "Upload/Signature", ".jpg.png.gif.tif.bmp");
+        var sysFile = await HandleUploadFile(file, "Upload/Signature", _imageType);
 
         var sysUserRep = _sysFileRep.ChangeRepository<SqlSugarRepository<SysUser>>();
         var user = sysUserRep.GetFirst(u => u.Id == _userManager.UserId);

+ 44 - 38
Admin.NET/Admin.NET.Core/Util/VerifyFileExtensionName.cs

@@ -1,14 +1,20 @@
-using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
-using System.Xml;
-using System.Xml.Linq;
-using System.Xml.Serialization;
+// 大名科技(天津)有限公司 版权所有
+//
+// 此源代码遵循位于源代码树根目录中的 LICENSE 文件的许可证
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动
+//
+// 任何基于本项目二次开发而产生的一切法律纠纷和责任,均与作者无关
 
 namespace Admin.NET.Core;
 
+/// <summary>
+/// 验证文件类型
+/// </summary>
 public static class VerifyFileExtensionName
 {
-    private static IDictionary<string, string> dics_ext = new Dictionary<string, string>();
-    private static IDictionary<string, HashSet<int>> ext_dics = new Dictionary<string, HashSet<int>>();
+    private static readonly IDictionary<string, string> dics_ext = new Dictionary<string, string>();
+    private static readonly IDictionary<string, HashSet<int>> ext_dics = new Dictionary<string, HashSet<int>>();
 
     static VerifyFileExtensionName()
     {
@@ -18,31 +24,31 @@ public static class VerifyFileExtensionName
         dics_ext.Add("49492A00", ".tif");
         dics_ext.Add("424D", ".bmp");
 
-        //PS和CAD
+        // PS和CAD
         dics_ext.Add("38425053", ".psd");
         dics_ext.Add("41433130", ".dwg"); // CAD
         dics_ext.Add("252150532D41646F6265", ".ps");
 
-        //办公文档类
-        dics_ext.Add("D0CF11E0", ".doc"); //ppt、doc、xls
-        dics_ext.Add("504B0304", ".docx");//pptx、docx、xlsx    
-
-        /**注意由于文本文档录入内容过多,则读取文件头时较为多变-START**/
-        dics_ext.Add("0D0A0D0A", ".txt");//txt
-        dics_ext.Add("0D0A2D2D", ".txt");//txt
-        dics_ext.Add("0D0AB4B4", ".txt");//txt        
-        dics_ext.Add("B4B4BDA8", ".txt");//文件头部为汉字
-        dics_ext.Add("73646673", ".txt");//txt,文件头部为英文字母
-        dics_ext.Add("32323232", ".txt");//txt,文件头部内容为数字
-        dics_ext.Add("0D0A09B4", ".txt");//txt,文件头部内容为数字
-        dics_ext.Add("3132330D", ".txt");//txt,文件头部内容为数字      
-        /**注意由于文本文档录入内容过多,则读取文件头时较为多变-END**/
+        // 办公文档类
+        dics_ext.Add("D0CF11E0", ".doc"); // ppt、doc、xls
+        dics_ext.Add("504B0304", ".docx"); // pptx、docx、xlsx
+
+        /* 注意由于文本文档录入内容过多,则读取文件头时较为多变-START */
+        dics_ext.Add("0D0A0D0A", ".txt"); // txt
+        dics_ext.Add("0D0A2D2D", ".txt"); // txt
+        dics_ext.Add("0D0AB4B4", ".txt"); // txt
+        dics_ext.Add("B4B4BDA8", ".txt"); // 文件头部为汉字
+        dics_ext.Add("73646673", ".txt"); // txt,文件头部为英文字母
+        dics_ext.Add("32323232", ".txt"); // txt,文件头部内容为数字
+        dics_ext.Add("0D0A09B4", ".txt"); // txt,文件头部内容为数字
+        dics_ext.Add("3132330D", ".txt"); // txt,文件头部内容为数字
+        /* 注意由于文本文档录入内容过多,则读取文件头时较为多变-END */
 
         dics_ext.Add("7B5C727466", ".rtf"); // 日记本
 
         dics_ext.Add("255044462D312E", ".pdf");
 
-        //视频或音频类
+        // 视频或音频类
         dics_ext.Add("3026B275", ".wma");
         dics_ext.Add("57415645", ".wav");
         dics_ext.Add("41564920", ".avi");
@@ -53,12 +59,12 @@ public static class VerifyFileExtensionName
         dics_ext.Add("6D6F6F76", ".mov");
         dics_ext.Add("3026B2758E66CF11", ".asf");
 
-        //压缩包
+        // 压缩包
         dics_ext.Add("52617221", ".rar");
         dics_ext.Add("504B03040A000000", ".zip");
         dics_ext.Add("1F8B08", ".gz");
 
-        //程序文件
+        // 程序文件
         dics_ext.Add("3C3F786D6C", ".xml");
         dics_ext.Add("68746D6C3E", ".html");
         //dics_ext.Add("7061636B", ".java");
@@ -66,11 +72,11 @@ public static class VerifyFileExtensionName
         //dics_ext.Add("4D5A9000", ".exe");
 
         dics_ext.Add("44656C69766572792D646174653A", ".eml"); // 邮件
-        dics_ext.Add("5374616E64617264204A", ".mdb");//Access数据库文件
+        dics_ext.Add("5374616E64617264204A", ".mdb"); // Access数据库文件
 
         dics_ext.Add("46726F6D", ".mht");
         dics_ext.Add("4D494D45", ".mhtml");
-        //
+
         foreach (var dics in dics_ext)
         {
             if (!ext_dics.ContainsKey(dics.Value))
@@ -79,6 +85,7 @@ public static class VerifyFileExtensionName
                 ext_dics[dics.Value].Add(dics.Key.Length / 2);
         }
     }
+
     /// <summary>
     /// 文件格式和文件内容格式是否一致
     /// </summary>
@@ -89,34 +96,35 @@ public static class VerifyFileExtensionName
     {
         if (stream == null)
             return false;
-        //
+
         suffix = suffix.ToLower();
         if (!ext_dics.ContainsKey(suffix))
             return false;
+
         try
         {
             foreach (var Len in ext_dics[suffix])
             {
                 byte[] b = new byte[Len];
                 stream.Read(b, 0, b.Length);
-                //string fileType = System.Text.Encoding.UTF8.GetString(b);
+                // string fileType = System.Text.Encoding.UTF8.GetString(b);
                 string fileKey = GetFileHeader(b);
                 if (dics_ext.ContainsKey(fileKey))
                     return true;
             }
         }
-        catch (IOException e)
+        catch (IOException)
         {
         }
         return false;
     }
+
     /**
      * 根据文件转换成的字节数组获取文件头信息
-     * 
-     * @param filePath
-     *            文件路径
+     * @param 文件路径
      * @return 文件头信息
      */
+
     private static string GetFileHeader(byte[] b)
     {
         string value = BytesToHexString(b);
@@ -125,7 +133,7 @@ public static class VerifyFileExtensionName
 
     /**
      * 将要读取文件头信息的文件的byte数组转换成string类型表示
-     * 下面这段代码就是用来对文件类型作验证的方法, 
+     * 下面这段代码就是用来对文件类型作验证的方法,
      * 将字节数组的前四位转换成16进制字符串,并且转换的时候,要先和0xFF做一次与运算。
      * 这是因为,整个文件流的字节数组中,有很多是负数,进行了与运算后,可以将前面的符号位都去掉,
      * 这样转换成的16进制字符串最多保留两位,如果是正数又小于10,那么转换后只有一位,
@@ -133,22 +141,20 @@ public static class VerifyFileExtensionName
      * @param src要读取文件头信息的文件的byte数组
      * @return 文件头信息
      */
+
     private static string BytesToHexString(byte[] src)
     {
-        StringBuilder builder = new StringBuilder();
+        var builder = new StringBuilder();
         if (src == null || src.Length <= 0)
-        {
             return null;
-        }
+
         string hv;
         for (int i = 0; i < src.Length; i++)
         {
             // 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写
             hv = Convert.ToString(src[i] & 0xFF, 16).ToUpper();
             if (hv.Length < 2)
-            {
                 builder.Append(0);
-            }
             builder.Append(hv);
         }
         return builder.ToString();