Grails中为静态资源设置过滤器

今天做了个上传文件功能的雏形,发现上传后的文件(URI)不受Grails的过滤器控制,用户不登陆也可以访问到这些资源,这自然就不安全咯。

开始还以为是uri匹配的不对,后来查阅文档才明白,Grails的过滤器只对controller有效,对静态资源无能为力(包括网站的各种图标)
引用
Static resources aren't served by a controller, so Grails filters (which are wrappers for Spring controller interceptors) won't fire for requests for them.


解决办法,回归原本
1. 在src/java或src/groovy下创建一个过滤器,可以让它什么都不做
package myoa

import javax.servlet.*

class StaticFilter implements Filter {
    @Override
    void init(FilterConfig filterConfig) {
        println('StaticFilter init')
    }

    @Override
    void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {
        println('StaticFilter doFilter')
    }

    @Override
    void destroy() {
        println('StaticFilter destroy')
    }
}

2. 创建配置文件
grails install-templates
编辑之
src/templates/war/web.xml

   <filter>
        <filter-name>staticFilters</filter-name>
        <filter-class> myoa.StaticFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>staticFilters</filter-name>
        <url-pattern> /file-store/*</url-pattern>
    </filter-mapping>

这样就做好了一个最简单的静态资源过滤器,uri在file-store文件夹的所有资源将被禁止访问。

3. 再进一步,可以完善这个doFilter功能,其实这就是Grails的过滤器的本质。 这里倒是有了个小心得,越本质的东西,看起来复杂,理解起来容易(好比是Servlet);封装过的东西,用起来简单,理解起来困难(好比是Grails)。所以要两者兼顾,先实用主义,把东西先做出来,然后慢慢体会最本质的东西,好歹现在都是open source的,看源码比看文档来得更透彻。
void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) {
        println('StaticFilter doFilter')

        HttpServletRequest request = (HttpServletRequest) servletRequest
        HttpServletResponse response = (HttpServletResponse) servletResponse
        HttpSession session = request.getSession(false) //若存在会话则返回该会话,否则返回NULL

        if (session?.getAttribute('loginUser')) {
            chain.doFilter(servletRequest, servletResponse);//放行。让其走到下个链或目标资源中
        } else {
            println('please login')
            response.sendRedirect(request.getContextPath() + "/user/login")
        }
    }

====有待研究====
staticFilter无效
<g:link url="${resource(dir: 'download', file: 'expense-this-month.xls')}">
http://localhost:8080/myoa/static/download/expense-multi-month.xls

staticFilter有效
<g:link uri='/download/expense-this-month.xls'>
http://localhost:8080/myoa/download/expense-multi-month.xls

你可能感兴趣的:(spring,servlet,grails)