背景

在项目中我们可能会存在一些静态资例如者图片、excel、pdf之类的文件访问是需要授权才可访问的。

错误示例
1、我们通过localhost/profile/girl.jpg可以访问到美女图片,假设图片是存储在我们的服务器的/home/data目录下,我们可以通过nginx的反向静态资源代理可以直接将profile的请求文件转入到/home/data下去读取图片文件。
2、我们可以将图片直接存储至云服务器,或者一个外网访问地址例如:https://yunurl/profile/girl.jpg。这种情况我们无需配置nginx代理。
以上两种情况都是在用户未认证,拿到地址即可访问文件

解决方案

引入shiro,springboot对文件的请求路径增加映射时shiro进行认证权限判断。
我们同样分两种情况
1、文件存储在本地,即与应用在同一服务器,例如我们的文件是在/home/data目录下,我们可以通过此配置来映射

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry)
    {
        registry.addResourceHandler("/profile/**").addResourceLocations("file:/home/data");
    }

以上配置使得访问localhost/profile/girl.jpg时会映射至本地路径下去查找文件,并且shiro会先对此请求进行认证的权限访问,如果没有登录访问此链接则会跳转至登录页面。
2、对于存储在云端的文件,我们同样也需要对其进行认证校验,而做法如上一致,结合addResourceLocations的源码我们分析


    /**
     * Add one or more resource locations from which to serve static content.
     * Each location must point to a valid directory. Multiple locations may
     * be specified as a comma-separated list, and the locations will be checked
     * for a given resource in the order specified.
     * <p>For example, {{@code "/"}, {@code "classpath:/META-INF/public-web-resources/"}}
     * allows resources to be served both from the web application root and
     * from any JAR on the classpath that contains a
     * {@code /META-INF/public-web-resources/} directory, with resources in the
     * web application root taking precedence.
     * <p>For {@link org.springframework.core.io.UrlResource URL-based resources}
     * (e.g. files, HTTP URLs, etc) this method supports a special prefix to
     * indicate the charset associated with the URL so that relative paths
     * appended to it can be encoded correctly, e.g.
     * {@code [charset=Windows-31J]https://example.org/path}.
     * @return the same {@link ResourceHandlerRegistration} instance, for
     * chained method invocation
     */
    public ResourceHandlerRegistration addResourceLocations(String... resourceLocations) {
        this.locationValues.addAll(Arrays.asList(resourceLocations));
        return this;
    }

静态资源的映射支持类路径、本地文件、并且支持url方式的路径映射,因此假设文件存储在https://yunurl/profile/girl.jpg此云路径下。
我们可以同样来通过此方法来映射

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry)
    {
        registry.addResourceHandler("/profile/**").addResourceLocations("https://yunurl/profile");
    }

shiro对于请求路径的拦截是默认在authc过滤级别下,因此只要保证我们的项目请求能够并shiro拦截,并且路径能映射到静态资源文件,则可以满足静态文件的访问权限控制


独上兰舟
119 声望5 粉丝

路漫漫其修远兮,吾将上下而求索。