通过后缀名和MIME-TYPE检查实现文件类型校验

Posted beyond-ms

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过后缀名和MIME-TYPE检查实现文件类型校验相关的知识,希望对你有一定的参考价值。

前言

文件上传是一个在开发中很常见的需求场景,通常出于安全考虑,我们会对上传的文件进行类型校验,其中常见的有后缀名校验,mime-type校验

话不多说,直接上代码

1.首先定义允许上传的文件类型白名单

private static final String[] suffixWhiteList = {"PNG","JPEG","JPG","GIF"};
private static final String[] mimeTypeWhiteList = {"image/jpeg","image/gif","image/png"};

2.后缀名校验

    /**
     * 文件后缀名校验
     *
     * @param fileName
     *            文件名称
     * @return
     */
    public static boolean suffixCheck(String fileName) {
        if(fileName == null || "".equals(fileName)){
            return false;
        }
        //从最后一个点之后截取字符串
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        //白名单匹配
        boolean anyMatch = Arrays.stream(suffixWhiteList).anyMatch(x -> x.equalsIgnoreCase(suffix));
        return anyMatch;
    }

3.mime-type校验,因为需要获取文件的mimeType,我引入了第三方的jar包(其他同样功能的jar包都可以)

    //MIME-TYPE工具包
    compile("net.sf.jmimemagic:jmimemagic:0.1.3")
    /**
     * MIMETYPE校验
     * @return
     */
    public static boolean mimeTypeCheck(MultipartFile uploadFile){
        if (uploadFile.isEmpty()){
            return false;
        }
        //文件名
        String fileName = uploadFile.getOriginalFilename();
        // 获取文件后缀
        String suffix=fileName.substring(fileName.lastIndexOf("."));
        File picFile = null;
        try {
            // 用uuid作为文件名,防止生成的临时文件重复
            picFile = File.createTempFile(UuidUtils.getUuid(), suffix);
            FileUtils.copyInputStreamToFile(uploadFile.getInputStream(),picFile);
            // MultipartFile to File
            MagicMatch match = Magic.getMagicMatch(picFile, false);
            String mimeType = match.getMimeType();
            // 白名单匹配
            boolean anyMatch = Arrays.stream(mimeTypeWhiteList).anyMatch(x -> x.equalsIgnoreCase(mimeType));
            return anyMatch;

        } catch (IOException e) {
            LOGGER.error("生成临时文件异常",e);
        } catch (Exception  e) {
            LOGGER.error("MIME-TYPE检查发生异常",e);
        } finally {
            //程序结束时,删除临时文件
            if (picFile.exists()){
                picFile.delete();
            }
        }
        return false;
    }

以上是关于通过后缀名和MIME-TYPE检查实现文件类型校验的主要内容,如果未能解决你的问题,请参考以下文章

CTF_文件上传

访问 Apache 的 Mime-Type 到扩展映射

WIN7/XP用注册表关联指定后缀名和打开程序(手动图文和C编程两种实现)

Findbugs+eclipse 排除个别校验

检查文件 mime 类型是不是与 php 中的扩展名匹配

linux 中的cksum如何通过java实现