[暂定用此方法]
一新项目,考虑到Flex做UI太方便了,准备用Flex做,遇到一个用户鉴权的问题。Flex本身是属于客户端的东西,无法获得Session,所以不能直接得知当前用户是否Session过期。
这里提到的解决方法是:写一个Filter,然后在doFilter()中,查看Session是否存在,如果不存在,就转向登录页面,比如SignIn.html。
看似简单,不过今天走了些弯路,我原先的web.xml配置如下:
<filter> <filter-name>authFilter</filter-name> <filter-class>org.charry.lib.rbac.filter.AuthFilter</filter-class> </filter> <filter-mapping> <filter-name>authFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Filter中转向到SignIn.html,这样有个问题:上面的配置会让所有的资源访问都会被转向SignIn.html,甚至对 Sigin.html本身的访问都会被转向SignIn.html,造成无限循环,浏览器会指出该错误。所以我在doFilter()里面判断当前访问的 资源的URI是否包含SignIn.html,如果包含,就不做redirect。不过,这样还是有问题,SignIn.html页面里面会引用一些其他 的资源,比如foo.js, bar.swf, foobar.gif等,对这些资源的访问也会被redirect。所以我尝试将Filter配置如下,也就是说只过滤html页面:
<filter> <filter-name>authFilter</filter-name> <filter-class>org.charry.lib.rbac.filter.AuthFilter</filter-class> </filter> <filter-mapping> <filter-name>authFilter</filter-name> <url-pattern>*.html</url-pattern> </filter-mapping>
这样还是会有问题:因为SWF文件可以访问,很多Flex项目的SWF文件是可以直接使用的,所以,还存在用户鉴权的问题。由于该项目用的是BlazeDS,我只要堵住所有的DataService的Servlet就可以了,所以我最后用了如下的配置:
<filter> <filter-name>authFilter</filter-name> <filter-class>org.charry.lib.rbac.filter.AuthFilter</filter-class> </filter> <filter-mapping> <filter-name>authFilter</filter-name> <url-pattern>/messagebroker/*</url-pattern> <url-pattern>*.html</url-pattern> </filter-mapping>
第一个模式匹配的目的是:让所有的AMF调用全部用过滤器检查一下权限,第二条的作用是所有的.html也要经过过滤器检查(此条不加,会出现刷新 未登录页面,不跳转的问题)。新的问题又来了,我原先的Session管理是用BlazeDS调用的,现在自己把路堵死了,所以只能再写个单独的 Servlet用来实现用户登录,完整的Filter和Servlet配置如下:
<filter> <filter-name>authFilter</filter-name> <filter-class>org.charry.lib.rbac.filter.AuthFilter</filter-class> </filter> <filter-mapping> <filter-name>authFilter</filter-name> <url-pattern>/messagebroker/*</url-pattern> <url-pattern>*.html</url-pattern> </filter-mapping> <servlet> <servlet-name>loginServlet</servlet-name> <servlet-class>org.charry.lib.rbac.servlet.ServletLogin</servlet-class> </servlet> <servlet-mapping> <servlet-name>loginServlet</servlet-name> <url-pattern>/loginServlet</url-pattern> </servlet-mapping>
经验证,方法可行,但总觉得比较麻烦,继续留意是否有更为简便的方法。