文件上传思路



@Service
public class FileServerImpl implements FileServer {

    public static final int maxWidth = 100;

    //拦截的url,虚拟路径
    public String pathPattern = "uploads";

    //文件磁盘路径
    @Value("${file.upload.path}")
    private String fileUploadPath;

    @Value(value = "${file.upload.suffix:jpg,jpeg,png,bmp,xls,xlsx,pdf}")
    private String fileUploadSuffix;

    @Value(value = "${file.upload.is-thumb}")
    private Boolean isThumb;

    @Value(value = "${file.upload.proportion}")
    private Integer proportion;

    @Autowired
    HttpServletRequest request;

    @Autowired
    FileMapper fileMapper;

    //文件上传
    @Override
    public FileEntity upload(MultipartFile file) {
        FileEntity fileRes = new FileEntity();

        if (file.isEmpty()) {
            // log.error("the file to be uploaded is empty");
            return fileRes;
        }
        List<String> suffixList = Lists.newArrayList(fileUploadSuffix.split(","));

        try {
            //校验文件后缀
            String originalFilename = file.getOriginalFilename();
            //获取文件类型
            String type = FileUtil.extName(originalFilename);
            //文件后缀
            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            if (!suffixList.contains(suffix)) {
                //log.error("unsupported file format");
                return fileRes;
            }

            //获取文件md5
            String md5 = SecureUtil.md5(file.getInputStream());

            // 从数据库查询是否存在相同的记录
            FileEntity dbFiles = fileMapper.queryByMd5(md5);
            if (dbFiles != null) { // 文件已存在
                return dbFiles;
            }


            String year = new SimpleDateFormat("yyyy").format(new Date());
            String month = new SimpleDateFormat("MM").format(new Date());
            String day = new SimpleDateFormat("dd").format(new Date());

            String fileDir = fileUploadPath;
            String filePath = File.separator + year + File.separator + month + File.separator + day + File.separator;

            //首次需生成目录
            File folder = new File(fileDir + filePath);
            if (!folder.exists()) {
                folder.mkdirs();
            }

            AtomicInteger counter = new AtomicInteger(0);
            String uniqueString = String.valueOf(Instant.now().toEpochMilli());

            String fileName = uniqueString + "." + suffix;
            String absolutePath = fileDir + filePath + fileName;
            file.transferTo(new File(absolutePath));
            //网页路径
            String dataFilePath = pathPattern + "/" + year + "/" + "/" + month + "/" + day + "/" + fileName;

            fileRes.setFilePath(dataFilePath);
            fileRes.setFileName(fileName);
            fileRes.setIp(request.getRemoteAddr());
            fileRes.setFileSize(file.getSize() / 1024);
            fileRes.setFileType(type);
            fileRes.setFileExt(suffix);
            fileRes.setFileMd5(md5);

            //判断是否生成缩率图
            if (isThumb) {
                createThumb(fileDir, filePath, uniqueString, suffix);
                String dataFileThumbPath = pathPattern + "/" + year + "/" + "/" + month + "/" + day + "/" + uniqueString + "_thumb." + suffix;
                fileRes.setThumbPath(dataFileThumbPath);
            }
            fileMapper.insert(fileRes);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
        return fileRes;
    }

    //生成缩率图
    @Override
    public String createThumb(String fileDir, String filePath, String fileName, String suffix) {
        String localPath = fileDir + filePath + fileName + "." + suffix;
        String thumbPath = fileDir + filePath + fileName + "_thumb." + suffix;

        //判断缩略图是否存在
        Path path = Paths.get(thumbPath);
        if (Files.exists(path)) {
            return filePath + fileName + "_thumb." + suffix;
        }

        File originalFile = new File(localPath);
        try {
            BufferedImage originalImage = ImageIO.read(originalFile);
            int imageWidth = originalImage.getWidth();
            int imageHeight = originalImage.getHeight();

            double thumbWidth = 0;
            double thumbHeight = 0;
            if (imageWidth > maxWidth || imageHeight > maxWidth) {
                thumbWidth = (double) imageWidth / (double) proportion;
                thumbHeight = (double) imageHeight / (double) proportion;
            }
            if (thumbHeight > 0) {
                // 创建缩略图
                BufferedImage thumbnail = new BufferedImage((int) thumbWidth, (int) thumbHeight, BufferedImage.TYPE_INT_RGB);
                Graphics graphics = thumbnail.createGraphics();
                graphics.drawImage(originalImage.getScaledInstance((int) thumbWidth, (int) thumbHeight, Image.SCALE_SMOOTH), 0, 0, null);
                graphics.dispose();

                // 输出到文件
                ImageIO.write(thumbnail, suffix, new File(thumbPath));
                return filePath + fileName + "_thumb." + suffix;
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
        return "";
    }


}
在进行文件上传入侵排查时,以下是一些常见的思路和步骤: 1. 审查上传功能:审查网站或应用程序中的文件上传功能,确保其具有必要的安全控制,如文件类型检查、大小限制、白名单/黑名单过滤等。检查是否存在配置错误或漏洞,可能导致不受限制的文件上传。 2. 分析上传的文件:对上传的文件进行详细分析,包括检查文件类型、文件结构、元数据等。使用防病毒软件对上传的文件进行扫描,以发现潜在的恶意文件。 3. 文件验证和过滤:实施严格的文件验证和过滤机制,包括验证文件的合法性、过滤可执行文件、脚本文件、潜在的恶意文件类型等。使用白名单和黑名单机制来限制允许上传的文件类型和大小。 4. 审查日志:仔细审查应用程序或服务器的日志记录,特别关注与文件上传相关的日志条目。检查是否存在异常的上传活动,如大量的上传尝试、异常的文件名、访问频率等。 5. 安全扫描:进行安全扫描和漏洞评估,以检测潜在的文件上传漏洞和安全弱点。使用专业的漏洞扫描工具,如网站漏洞扫描器,来发现可能的漏洞。 6. 异常行为检测:监控服务器和应用程序的行为,检测异常的上传行为。这可以包括检测大型文件上传、非正常的上传频率、未经授权的文件上传等。 7. 更新和补丁:确保应用程序、服务器和相关组件的软件和补丁是最新的,以纠正已知的漏洞并提供更好的安全性。 8. 清理和恢复:如果发现恶意文件或入侵行为,立即采取措施清理受影响的系统,并还原到安全的状态。同时,对受影响的账户和用户进行必要的密码重置和安全措施。 以上是一些常见的文件上传入侵排查思路,但具体的步骤和方法可能因情况而异。建议在进行排查时,参考相关安全实践,并根据具体环境和需求来制定合适的入侵排查策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值