背景
在项目中我们可能会存在一些静态资例如者图片、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拦截,并且路径能映射到静态资源文件,则可以满足静态文件的访问权限控制