文件访问权限控制

前言

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

场景:对磁盘上的视频文件访问进行控制,因为视频可能包含敏感信息,所以不能让任何人都能随意访问。

思路

  • 访问视频

    视频文件存在专门磁盘目录下,如何让视频能被访问到?在SpringBoot中可以配置虚拟路径映射,使用ResourceHandlerRegistry 将本地磁盘路径映射成url来实现。

  • 访问控制

    使用Filter做访问控制,对上述映射出来的url进行拦截并校验访问权限。

实现

访问视频

  • 定义配置

    video-access:
      enable: true
      # url不以 / 结束
      url: /video
      # location以  / 结束
      location: G:/tmp/video-access/
    复制代码
    @Data
    @ConfigurationProperties(prefix = "video-access")
    @Component
    public class VideoAccessConfig {
    
        // 是否开启访问校验
        private boolean enable = true;
    
        // 映射url
        private String url = "";
    
        // 视频文件路径
        private String location = "";
    }
    复制代码
  • 添加映射

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
    
        @Autowired
        private VideoAccessConfig videoAccessConfig;
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler(videoAccessConfig.getUrl() + "/**")
                    .addResourceLocations("file:" + videoAccessConfig.getLocation());
        }
    }
    复制代码

访问控制

  • 定义Filter

    public class VideoAccessFilter extends OncePerRequestFilter {
    
        private boolean accessEnable;
    
        public VideoAccessFilter(boolean accessEnable) {
            this.accessEnable = accessEnable;
        }
    
        @Override
        protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
            // TODO:此处自定义访问控制逻辑
            String token = httpServletRequest.getQueryString();
            if (accessEnable && Objects.isNull(token)) {
                httpServletResponse.getOutputStream().write("Access Denied".getBytes(StandardCharsets.UTF_8));
            } else {
                filterChain.doFilter(httpServletRequest, httpServletResponse);
            }
        }
    }
    复制代码
  • 拦截url,使用FilterRegistrationBean注册Filter

    @Bean
    public FilterRegistrationBean filterOneRegister() {
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>();
            filterRegistrationBean.setFilter(new VideoAccessFilter(videoAccessConfig.isEnable()));
            filterRegistrationBean.addUrlPatterns(videoAccessConfig.getUrl() + "/*");
            return filterRegistrationBean;
        }
    复制代码

测试

映射图片路径方便测试,测试urlqueryString表示有权限

  • 映射文件夹

文件夹.PNG

  • 无权限http://localhost:8080/video/miruiki.jpg

访问异常.PNG

  • 有权限http://localhost:8080/video/miruiki.jpg?token=1231

正常访问.PNG

结尾

如果文章对你有帮助,请点 赞?? 支持一下。若有错误之处或有更好的建议,欢迎指正,谢谢。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享