`
alucardggg
  • 浏览: 8921 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

使用BIRT报表时的认证问题的解决以及注意事项

阅读更多

相信在目前的报表解决方案中, Birt为比较优秀的一种也是大多数偏好open source的人会优先选用的一种, 至于好处和优点, 在此不做累述, 下面就讨论一些集成了birt的viewer环境, 而有安全机制要求的系统的解决方案, 以及在部署时的一些注意事项, 最后, 为了解决这些实际的问题, 笔者写了一个swing的java小工具帮助使用者进行部署

* 所有讨论基于Birt 2.2
目前需要解决的问题:
1. Birt报表引擎如何和当前应用集成
2. 如果使用Birt官方的viewer环境, 如何解决安全问题
3. 有关安全问题的讨论

这里提出一个可行的解决, 事实上, 我们项目也是用了该解决方案使的项目成功上线
对于birt的集成, 网上有很多解决方案, 在此不累述
解决方案不外乎几种:
A. 直接在项目的web环境内调用report engine, 手动控制Birt的api使用
优点: 完全控制报表整个产生过程
缺点: 开发代价大, 代码质量要求高, 项目测试过程复杂, 高级功能需要手动写代码
B. 应用内集成Birt的viewer环境
优点: 开发代价小, 项目测试简单, 可以使用多种Birt的高级功能, (比如TOC,分页等)
缺点: 不能完全控制报表, 对于外部访问来说, Birt viewer就是一个黑盒, 很难控制
C. 结合A. B的解决方案, 既是使用Birt viewer, 又在恰当的地方插入一些自己需要的code
优点: 开发代价不高, 自己能对关键过程做控制, 项目测试类似B
缺点:
- 修改了birt的源文件, 对于birt的版本更新会造成额外的维护量
- Birt viewer是独立的项目, 会造成开发和代码版本控制上的不便
- 由于Birt viewer要build发布, 在部署的时候会带来不便(目前2.2下面build是个问题)

解决方案A过于复杂, 在此讨论B和C方案实现下的安全性问题
如何集成Birt的viewer, 在此不是重点, 网上有很多解决方案
将Birt的viewer环境集成后,由于在web.xml里面配置了Birt的servlet入口(比如preview, run, frameset等), 因此访问报表的url会交由Birt的serlvet处理,如何对于这些url做控制来实现安全性呢?

如果有以下安全需求需求:
1. 对于不同的角色进行访问控制
2. 对于不同角色下面的权限粒度进行访问控制
3. 对于任何形式的url进行访问控制, 由于使用了birt viewer接收url, 对于请求的url有着严格的控制

从测试驱动开发的角度来说,测试该权限系统需要注意以下方面:
1. URL测试,为权限控制到URL级别,即为权限不光控制页面输入,同时也对请求的URL有严格的过滤,角色或帐号不能跨自己的域请求报表数据,全部权限测试都涉及到页面请求和直接模拟URL请求2部分
2. 角色RA登陆后看到的是不是角色RA的全部报表

测试点一:是不是角色A的报表

测试点二:是不是角色A的全部报表
3. 角色RA登陆后能访问的报表资源RESA,在不是角色RA的情况下或者RA没有Login的情况下是否能被访问
测试点一. 不登录请求资源(URL)
测试点二. Session Expired请求资源(URL)
测试点三. 跨域请求资源
      1. 使用非RA的角色或用户请求RA的资源RESA
      2. 修改URL的带有认证信息参数,验证是否能请求到资源
      3. 在角色A的情况下,使用带自己的验证信息的URL请求其他角色的资源

      4. 使用缺少参数或者增加无意义参数请求资源(比如在URL里面删除startDate等), 增加一些破坏性参数请求
      5. 使用sql注入攻击
      6. 使用其他的URL攻击, 目的: 看到跨权限域的报表
4. Logout测试

测试点一:logout后是否能进行上述的全部操作或者请求到资源

测试点二:logout后是否能能通过页面后退/重新刷新/直接请求URL 重新登录

5. 屏蔽全部birt viewer中的默认serlvet, 只留下需要的servlet


为了解决上述问题, 我们需要对于访问报表模块的url进行控制和限制, 容易想到的一种解决方案是使用Filter拦截url, 如果url中带有的验证信息和session中存储的一致, 则视为通过验证, 将该url转由birt的servlet处理, 从而从应答中得到渲染后的报表

要使用以上方法需要注意几个地方:

1. 对birt viewer expose出来的全部url-pattern都要进行filter拦截, 对于其他未使用的url-pattern映射和servlet, 必须加以禁用

2. 保证在web环境下只有filter能转发请求到birt viewer的servlet

3. 要对报表参数进行拦截, e.x: 如果报表A定义了参数Pa, Pb, 则fitler需要检测Pa, Pb参数必须存在, 不为空的情况, 因为目前birt viewer中, 如果检测参数不存在或未填而弹出参数面板, 这样会给安全拦截带来不必要的麻烦, 用户可以使用自己的认证信息, 在参数面板中输入其他资源的参数而绕过认证


目前由于没找到禁用参数面板的方法, 则使用拦截器拦截全部的URL参数组合, 这样带来的坏处是: 对于处理同一角色下的报表集合, 则需要在同一逻辑段中判断所有情况, 并且报表的URL中带有的参数需要一个兼容全部参数的全集



为了避免以上问题, 方案B是对方案A的一种改进

方案B的解决思路为:

1.        将权限拦截移至BIRT VIEWER SERVLET 内部,由阅读BIRT源代码可知, 在BIRT VIEWER SERVLET内部也有认证接口代码,只不过没有实现,说明BIRT是扩展和保留了这种可能性

--引用BIRT 2.2 源代码:

package org.eclipse.birt.report.servlet

Class: BirtEngineServlet

    /**
     * Local authentication.
     *
     * @param request
     *            incoming http request
     * @param response
     *            http response
     * @return
     */
    protected boolean __authenticate(HttpServletRequest request,
               return true
    }

由源代码可知: 目前BIRT中的源码保留该接口, 返回true则通过认证, 返回false则被reject


2.        如果在Birt Viewer内部的servlet进行拦截,则任何的内部请求最终都会通过Birt viewer serlvet, 该请求无论是谁发起, 来自何方,  这样就全面的拦截了一切资源请求

 

3.        BIRT内部的Servlet可以调用开发者的认证类,此类的灵活性较大可以任意扩展

4.        通过加入一个java包来单独的实现权限模块,这样整个架构和逻辑完全可以自己控制

 

当然, 此方案的缺点在上文已经提了, 用户可根据自身项目情况适当调整解决方案, 在项目进度要求紧, 资源紧张, 而安全要求高的情况下, 方案B能较好的满足项目需要

 

下面对比下上述2中解决方案:

 

方案A的认证过程:

由方案A可知

 

BIRT SERVLET 没有检测 URL 权限的任何能力,任何 URL 只要到达了 BIRT SERVLET 都认为是合法而导致 BIRT REPORT ENGINE 的运行从而渲染出报表,对于如何 URL 直接到达 BIRT SERVLET ,唯一的安全拦截就是 AOP authentication module 这个 Filter ,对于这种情况,由于 BIRT SERVLET 是公开的,所以 Filter 需要拦截全部的 URL 组合情况,包括参数、资源、角色等,对于这样的拦截方式,如果有其他模块调用并转发了 BIRT SERVLET ,或者在通过 Filter 之后又修改了 URL 访问 SERVLET ,那么拦截是不起作用的

 

方案B的认证过程:

对于B方案的拦截过程,只要有请求发送到 BIRT SERVLET ,则 BIRT SERVLET 会调用 AOP authentication module 进行认证,如果通过则继续处理报表,如果不通过则 reject, 由于 BIRT SERVLET 是调用 REPORT ENGINE 唯一的入口,所以对于此入口的控制就可以控制任何企图直接调用 REPORT ENGINE 的行为,在这样的解决方案中,即使其他模块调用或转发了请求到 BIRT SERVLET ,则一样会被拦截

 

2 种解决方案的对比,我们可知:使用方案 B 能解决方案A不能解决的认证问题, 此方案缺点在于由于 BIRT SERVLET BIRT Viewer 框架中的模块,要插入 AOP Authentication module, 则我们需要修改 BIRT 的源文件.

 

Birt 源文件可从Birt的官方网站下载, 以下是我使用的CVS目录:

 

当下完Birt Viewer这个项目后, 将其导入Eclipse, 并解决包依赖的问题之后, 在Birt Viewer的build path中引用我们自己的项目, 就可以开始动手修改Birt Viewer的源文件了, 并且能在birt项目中调用我们自己项目的类

 

首先先要设计认证模块, 认证模块的设计思路为:

如果 module 应答为 false ,则认证不通过, true 为通过, module 通过公开一个 IAuth 接口给 BIRT SERVLET 来实现,接口方法为 boolean doAuth()

 

和Birt Viewer的集成方法为:

如图:

BaseAuth中定义了如下方法:

 

 

/**

  * 认证顺序为

  * 1. 认证 URL ,如果成功则设置资源权限

  * 2. 认证用户 session 如果成功则设置用户权限

  * 3. 认证角色

  * 4. 认证最小粒度

  */

public abstract class BaseAuth {

   

    /**

      * 认证用户角色

      * 即角色决定能访问的资源

      * 不同角色间的资源需要访问控制

      */

    protected abstract boolean authByRole();

   

    /**

      * 同一角色下,认证用户权限最小粒度

      * 最小粒度间的资源需要访问控制

      */

    protected abstract boolean authByMeta();

   

    /**

      * 检查用户的 session 是否合法,以及是否通过认证,是否过期等

      */

    protected abstract boolean authUserSession();

   

    /**

      * 检查 URL 的基本校验

      */

    protected abstract boolean authURL();

}


IAuth中的方法则为:

public interface IAuth {

    /*

     * 验证方法

     * ture -> 验证成功

     * false -> 验证失败

     */

    public boolean doAuth();

}

 

而在AuthByHttpRequest这个实现类中, 目前的实现是基于httprequest的认证, 将来可能会有通过IDAP, webservcie等认证方式, 根据项目的不同而实现不同

 

- doAuth() 返回的应是各个认证方法的逻辑与(&)运算, 比如

 

public   boolean doAuth() {

      return (authURL() && authUserSession() && authByRole() && authByMeta());

}

 

而在各个方法的实现根据项目和业务的不同而不同, 在此可自行调整

 

* Birt Viewer Servlet 的改动:

目前笔者改动的为

package org.eclipse.birt.report.servlet;

Class: BirtEngineServlet

为什么改动这个类,原因在于使用的servlet url pattern为preview, preview对应最基本的调用birt report engine的servlet, 不加任何的ajax, 或者webservice调用,因此也是速度最快的,顺便提一下,birt2.2版本的frameset这个servlet有bug, 当用frameset 在FreeBSD下渲染报表时,(由于Java没有发布FreeBSD版的官方JDK,目前使用的为非官方的DiabloJDK), 会出现CPU100%的情况,而使用preview却没有任何问题

 

实现 __authenticate  方法:

 

public   boolean _authenticate(HttpServletRequest request,
            HttpServletResponse response) {

 

                System.out.println("invoke the birt servlet!");
        IAuth au = AuthFactory.getHttpReqBasedAuth(request, response);
        boolean isAuth = au.doAuth();
        if(!isAuth) {
            try {
                response.sendRedirect(ERROR_URL);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
       
return isAuth;

}

 

这样就以最小的改动,将认证模块集成到Birt Viewer内部,接下来的问题就是如何编译成Viewer.jar并且发布到项目中

 

- 编译和部署

由于birt2.2的build过程和原来的完全不一样,笔者build了几次都失败了>_<, 如果有人知道如何使用随项目发布的ant build编译成功,不胜感激!

我采用的是比较简单的做法:直接替换class, 方法为:

1. 先在Eclipse通过编译,然后在output里面找到对应的BirtEngineServlet.class

2. 找到项目依赖的viewer.jar, 解压缩并替换掉BirtEngineServlet.class

3. 打包成新的viewer.jar(可以打包成.zip, 然后改个名字)

 

将新的viewer.jar引入到目前项目,则认证模块就可以开始工作了

 

在开发Birt报表过程中,开发者可能会发现一些数据库连接的问题

比如:目前有10张报表都使用同一个连接配置,比如连接到localhost 的mysql

在部署的时候可能会要去修改报表的连接,比如连接到服务器的mysql

则目前birt的版本提供了library功能,也就是说,只要在library里面配置了数据源,其他报表引用librar里面的即可

但是会有开发者发现有的时候并不起作用,原因在于:

只要在某张报表的design界面中打开了数据源连接,则会在该报表的xml源码中自动加入:

    <data-sources>
        <oda-data-source extensionID="org.eclipse.birt.report.data.oda.jdbc" name="Data Source" id="6"
 extends="datasource.Data Source">
            <property name="odaDriverClass">org.postgresql.Driver</property>
            <property name="odaURL">jdbc:postgresql://192.168.100.1:5432/testproperty>
            <property name="odaUser">user</property>
            <encrypted-property name="odaPassword" encryptionID="base64">c3UydmVu</encrypted-property>

        </oda-data-source>
    </data-sources>

 

只要有以红色标注的部分存在,那么birt一定会优先调用此段配置,而此段配置是每张报表独立的-_-!,也就是说,如果有20张报表,则要手动修改每张报表的配置

解决方案为手动删除掉此红色部分,那么birt又会优先调用library里面的配置项

 

但是具体开发过程中,开发者如果不小心点开了数据源配置,而加入此段代码,在部署时又没有发现,则部署时配置的数据库连接将不起作用

而在开发中,开发者对于每张报表的debug,切换数据库连接测试,是很常见的事

为了解决这个问题,笔者为birt2.2的报表开发了了一个小工具,该工具能部署前使用,一次性修改所有报表的连接

 

下载OdaDataSetting.zip并解压缩

里面有2个jar

BirtDesignToolWithGUI.jar 为图形化界面,适用于windows下面直接运行

BirtDesignTool.jar 为命令行输入,适用于unix系统

界面:

 

点击"Process" 则开始处理报表

目前版本中,关闭UI可能Java处理进程并未关闭,请手动在任务管理器里面杀掉进程即可

 

希望大家能解决和BIRT有关的任何问题,欢迎讨论

分享到:
评论
2 楼 alucardggg 2014-08-12  
marsseeker 写道
这样每次版本升级都要去改一遍源代码了,好痛苦啊!

我现在都直接用sed命令做了。。。
1 楼 marsseeker 2014-02-10  
这样每次版本升级都要去改一遍源代码了,好痛苦啊!

相关推荐

    Birt报表操作手册

    Birt报表操作手册 Birt报表操作手册是一个功能强大的报表设计和生成工具,提供了灵活的报表设计和生成功能。...通过了解Birt报表操作手册中的知识点,可以更好地使用Birt报表操作手册来设计和生成报表。

    Birt报表开发手册

    在设计报表时,需要考虑报表的结构、布局和样式。Birt提供了多种报表元素,包括文本、表格、图表、图片等,可以根据需要添加和排列这些元素。 六、Birt报表输出 Birt报表输出支持多种格式,包括PDF、Excel、Word、...

    birt报表参数的使用

    报表参数可以用于报表的生成,例如在报表中使用报表参数customernum,Birt会使用由报表参数customernum传入的值填充Where条件,生成结果数据集。 6. 源代码级使用 Birt报表参数可以在源代码级使用,例如使用Java...

    birt 报表教程 中文

    - 分析报表设计中遇到的问题及解决方案。 **4.2 最佳实践** - 提供BIRT报表设计的最佳实践建议。 - 包括性能优化、用户体验改进等方面。 #### 五、结语 通过本篇教程的学习,读者能够掌握BIRT报表设计的基本流程...

    BIRT报表使用说明

    ### BIRT报表使用说明 #### 一、下载与安装BIRT相关软件 为了开始使用BIRT报表工具,首先需要下载并安装相应的软件。Eclipse Marketplace提供了BIRT Report Designer的下载链接,适合在Eclipse(包括MyEclipse)...

    BIRT报表学习手册

    BIRT的核心特性包括一个直观的报表设计器,以及可嵌入到应用服务器中的运行时组件。 1. 报表介绍 BIRT报表设计环境类似于流行的网页编辑工具Dreamweaver,使得报表设计变得简单直观。用户可以通过拖放方式构建报表...

    birt报表,很好的java报表插件

    1. **BIRT学习指南**:目录"BIRT"可能包含一系列教程、文档或示例,帮助初学者了解BIRT的基本概念、架构、设计界面以及如何创建和部署报表。 2. **报表项目实践**:"My Reports"目录下的内容可能包含用户根据学习...

    Birt报表注意Birt报表注意Birt报表注意Birt报表注意

    虽然给定的部分内容似乎并不完全清晰,但从“BIRT报表注意”这一重复出现的关键词来看,我们可以推测作者可能希望强调在使用BIRT设计报表时需要注意的关键点。通过对上述知识点的深入探讨,我们不仅了解了BIRT的基本...

    BIRT报表开发手册

    Web 应用程序开发的基于 Eclipse 的开源报表系统 特别之处在于它是以 Java 和 JavaEE 为基础 BIRT 有两个主要组件:基于 Eclipse 的报表设计器 以及部署到应用服务器上的运行时组件 "&gt;BIRT报表中文开发手册 PDF版本 ...

    BIRT报表学习手册-中文

    对于BIRT报表学习手册,这篇文章将详细介绍BIRT报表的使用方法和技巧,从基本的报表设计到高级的报表功能,涵盖了许多实用的知识点。 一、去掉BIRT报表自动生成的日期时间 在BIRT报表中,有时候我们不需要显示报表...

    birt公用CSS样式

    3. 使用说明.txt:这是一个文本文件,可能包含了如何在BIRT报表中引入和使用birt.css的步骤,以及可能的注意事项。比如,如何在BIRT报表设计环境中导入CSS文件,如何在报表元素上应用样式类,或者如何自定义样式以...

    maximo系统birt报表的eclipese开发配置及导入系统

    Maximo系统是一款企业资产管理和工单管理软件,而BIRT(Business Intelligence and Reporting Tools)是Eclipse基金会的...在报表设计时,合理利用BIRT提供的图表、表格、过滤器等功能,可以创建出既实用又美观的报表。

    birt报表合并以及表头锁定功能的实现

    birt报表合并以及表头锁定功能的实现。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

    Birt报表工具设计指南

    要在Eclipse中使用Birt,首先需要下载并安装Birt运行时环境和Birt视图插件。安装完成后,可以在Eclipse中找到Birt报告设计器,通过它可以创建、编辑和运行报表。 ### 3. 报表设计基础 - **数据源**:在Birt中,...

    birt报表详细中文文档

    BIRT(Business Intelligence and Reporting Tools)是开源的报表系统,由Eclipse基金会维护,用于开发数据可视化和商业智能解决方案。这个“birt报表详细中文文档”提供了全面的指南,帮助用户理解和利用BIRT的各项...

    birt报表开发 (二)、birt报表初体验-第一个报表

    Birt(Business Intelligence and Reporting Tools)是开源的企业级报告解决方案,它提供了一种强大的方式来创建、设计和部署复杂的报表。在这一阶段,我们将了解如何着手创建你的第一个Birt报表。 首先,我们需要...

    birt报表的官方API

    在开发BIRT报表时,理解和掌握其官方API至关重要,因为这将直接影响到报表的设计、数据处理以及功能实现。 首先,我们要理解BIRT API的核心组成部分: 1. **Report Designer API**:这是BIRT的图形化报告设计界面...

    birt报表工具

    综上所述,BIRT 报表工具是一款功能强大、易于使用的报表生成工具,它不仅能满足企业日常的数据处理需求,还能适应未来技术发展趋势。无论是初学者还是高级用户,都可以从 BIRT 中找到满足自己需求的功能。

Global site tag (gtag.js) - Google Analytics