finereport资源finereport6.5权限管理集成说明_第1页
finereport资源finereport6.5权限管理集成说明_第2页
finereport资源finereport6.5权限管理集成说明_第3页
finereport资源finereport6.5权限管理集成说明_第4页
finereport资源finereport6.5权限管理集成说明_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、FineReport 权限管理集成(J2EE 应用篇)前言现在的信息系统,95%以上都需要结合权限管理进行整个系统的使用权限划分。java 报表FineReport 采用了目前比较流行的“基于角色的权限管理”方案,整个权限管理过程中以角色为桥梁,可分配用户角色,对角色设置不同的权限范围,也就是不同报表,可支持无限层级的扩展。此文档说明例子是,利用原有系统的权限管理,对java 报表FineReport做出的报表进行权限管理,以达到代码的重用,更好的方便用户使用。本例结合 J2EE 应用详述两者集成方案。一首先简单介绍一下普通管理系统的权限管理方案。1.权限。系统中所权限管理限信息,在数据库中应

2、该是树状结构。举个例子:用户管理查看用户在数据库中结构如下:本例权限设计表: HYPERLINK http:/w/ http:/w/forumimages/f-permisdesign table.jpg2.角色。系统中涉及的角色,也可以看成是用户类型。比如,一个系统中可以有超级管理员,不同部门的人拥有不同角色,如财务部门,销售部门。再给每个角色分配不同的权限。本例角色设计表: HYPERLINK http:/w/ http:/w3.用户。系统中涉及到的所有用户,指定每个用户所拥有的角色,这样用户再根据角色拥有的权限达到权限管理的效果。本例用户表:/forumimages/f-role des

3、ign table.jpg HYPERLINK http:/w/ http:/w/forumimages/f-user design table.jpg上述三张表之间的关系为,用户与角色多对多关系,角色与权限也是多对多系这样就需要额外的两张表他们之间关系,如下图所示。User_role HYPERLINK http:/w/ http:/w/forumimages/f-user role.jpgUserinforole HYPERLINK http:/w/ http:/w HYPERLINK http:/w/ http:/w/forumimages/f-user design table.jpg

4、/forumimages/f-role design table.jpgRole_path HYPERLINK http:/w/ http:/w/forumimages/f-role path.jpgRolepath/forumimages/f-role design table.jpg/forumimages/f-path.jpg HYPERLINK http:/w/ http:/w HYPERLINK http:/w/ http:/w以上表中的信息是系统中存在两种主要功能权限,一种是公共信息模块,另一种是管理模块、以及三种角色:管理员,财务部,销售部;管理员拥有全部权限,另外两种整体结构图

5、如下:只能浏览公共信息模块。 HYPERLINK http:/w/ http:/w/forumimages/f-structure chart.jpg具体流程是:用户初次请求(携带用户名和),交到处理页面,如 servlet,然后根据用户名和去数据库中验证,如果验证失败则转到登录页面提示帐号错误。如果验证通过,根据用户 id 获取角色信息,根据角色信息获取该用户所拥角色的所限,然后将获得权限信息返回给用户进行菜单展示。本例中是将权限信息做成目录树结构。为了防止用户根据地址栏信息,直接输入 URL,绕过权限菜单进行有两种解决方案:。1:在用户根据角色取权限信息的同时,将该用户所能的权限信息存放到

6、ses ses作用域中。在用户之前,增加一个权限过滤器,根据其的 url 与。作用域存放的权限二者进行比较,如果不合法则对其进行2:同样在用户前增加一个过滤器,只是用户在初次时将其角色信息的权限,再根据作用存放与作用域中。用户在的时候根据其 url 获取要域中的角色到数据库中进行查找该权限是否符合此角色,如不符合将其进行拦截。两种方案比较:第案在执行效率上较第二种稍高,不用每次去数据库查找,第二种方案可以做到实时性,在登录后如果数据库发生改变可以不受影响。请求过程示意图: HYPERLINK http:/w/ http:/w/forumimages/f-procedure chart.jpg最

7、终使用 userinfo 表中的 admin 登录系统后将看到如下菜单。 HYPERLINK http:/w/ http:/w/forumimages/f-.jpg而使用 sale 用户登录系统后只能看到公共信息部分,如下所示: HYPERLINK http:/w/ http:/w/forumimages/f-public information.jpg二FineReport 与普通管理系统的权限集成方案。首先介绍下 java 报表成。1.设计报表FineReport 做出的报表与普通系统不做权限的集假设设计两张报表 risk.cpt, season.cpt,分别是财务部门销售部门的。位置分别

8、放在java 报表FineReport 工程下 reportlets 下的 finance 和 sale文件夹下面。如下图所示: HYPERLINK http:/w/ http:/w2.将/forumimages/f-design report.jpg用 FineReport 设计好的报表拷贝到现有系统工程下,具体步骤将%FineReport_HOME%WebReportWEB-INF 目录下面的lib,reportlets,resour四个目录到现有系统的 WEB-INF 文件夹下, %Tomcat_HOME %webappsAuthorityDemoWEB-INF 下。Lib 文件夹应该和

9、原有的进行合并,此例工程名为 AuthorityDemo。 HYPERLINK http:/w/ http:/w3.整合 web.xml。只需要在已有工程的 web.xml 中添加相应的与子元素。将%FineReport_HOME%/WebReport/WEB-INF 下的 web.xml 中如下的部分到%tomcat_home%/webapps/ AuthorityDemo /WEB-INF 下的web.xml 中,在最后一个之后: HYPERLINK http:/w/ http:/w/forumimages/f-egration.jpg后结果: HYPERLINK http:/w/ htt

10、p:/w/forumimages/f-after copy.jpg这样在地址栏直接输入报表地址:就可以到已经做好的报表。如下所示 HYPERLINK http:/w/ http:/w/forumimages/f-input.jpg如果可以成功说明整功,下面要做的就是加上权限过滤。4.配置数据库中相应权限信息在原有的系统权限表中相应的权限菜单,如下图所示: HYPERLINK http:/w/ http:/w/forumimages/f-configure information.jpg红色部分为后添加的报表模块权限,加入的内容是模拟两个部门的报表,财务部门的风险报表和销售部门的销售报表,pat

11、hurl 为报表报表的路径。再给不同角色赋予相应权限,在 role_path 表中相应信息,如下图: HYPERLINK http:/w/ http:/w这角色R002可以/forumimages/f-insert role path.jpg的信息是角色R001,可以pathid 为 p009,p011的报表,的是 p009 报表,角色R003,可以的是 p011 报表。这样管理员拥有两张报表浏览权限,每个部门只能查看自己部门的报表。数据库中的数据弄完后。5.此例通过过滤器实现权限过滤。首先配置 web.xml,加上一个权限 filter。效果如下: HYPERLINK http:/w/ ht

12、tp:/w/forumimages/f-configure web xml.jpg下面就来实现 AuthorityFilter 中的方法:思路分析:由于这个过滤器只针对用 java 报表 FineReport设计的报表,因此只需将是报表请求截获进行处理,由于报表的地址后面有一个reportlet 参数,只需判断是否有此参数传递,可以判断request.getParameter(reportlet)的值,如果为null 表明报表,可以不做处理,如果不为 null,转到进行判断。的不是判断内存中是否保存有用户登录信息,如果没有登录,可以转到登录页面让用户登录,如果已经登录则转到进行判断。取出当前用

13、户的角色以及 reportlet 参数值(即报表名),根据角色与参数(即在数据库中定义的权限)到数据库中查找看该报表是否符合该角色权限,如果符合将请求的报表返回给用户,否则提示用户没流程图如下:限该报表。 HYPERLINK http:/w/ http:/w/forumimages/f-procedure chart2.jpg这样管理员登录后将看到以前系统模块和报表模块,如下图所示: HYPERLINK http:/w/ http:/w/forumimages/f-umodule.jpg使用 sale 帐户登录只能看到销售部门的报表, HYPERLINK http:/w/ http:/w/fo

14、rumimages/f-sales report.jpg如果用 sale 登录的帐户想在地址栏中直接输入财务报表的地址进行器就会进行过滤,返回错误页面。,过滤 HYPERLINK http:/w/ http:/w/forumimages/f-error.jpg附 Filter:具体代码如下:public void doFilter(ServletRequest req,ServletResponse resp,FilterChain chain) throws IOException, ServletException HttpServletRequest request = (HttpSer

15、vletRequest)req; HttpServletResponse response = (HttpServletResponse)resp;String name = request.getParameter(reportlet);if(name != null) /说明的报表,只对cpt模板进行过滤User user = (User)request.getSes().getribute(user);/获取用户信息if(user = null) /没有用户信息,用户没有登录,让他登录request.setribute(errormsg, 您还没有登录系统,请先登录!);request.

16、getRequestDispatcher(login.jsp).forward(req, resp);return;else /登录后用户取角色和报表名称到数据库进行验证Loginlogin= new Login();String role = (String)request.getSes().ge,后面报表中需要用到tribute(role);/获取角色/将角色存入sesrequest.getSes().setribute(fr_authority,role);/过滤地址中多余的斜线while(name.startsWith(/)|name.startsWith()name = name.s

17、ubstring(1,name.length();ckAuthority(name,role);合法,返还报表flag = loginif(flag)/flag为true,chain.doFilter(request, response);else/flag为false,不合法转到错误页面,提示没限!);request.setribute(errormsg, 您没限此request.getRequestDispatcher(error.jsp).forward(req,return;resp);elsechain.doFilter(request, response);其中 checkAuth

18、ority(name,role) 方法代码:publiccheckAuthority(String name,String role)flag = false;Connection conn = null; PreparedSement ps = null; ResultSet rs = null;try /sql:根据角色与报表名称查询数据库 该角色是否对应有此报表的权限,/如果查出,表明可以,返回trueString sql = SELECT pathurl,path.pathid FROM path,role,role_path WHERE role.roleid IN(+role+)

19、AND role_path.pathid=path.pathid AND role_path.roleid=role.roleidpathurl=+name+;ANDconn ps =rs = DBHelp.getConnection();conn.prepareSement(sql);ps.executeQuery();if(rs.next() flag = true; catch (Exception e) e.prStackTrace();return flag;三原有系统与报表工程放在不同应用中。上面方法是将报表工程放到原有系统中,下面介绍报表系统与原有系统分开部署放置。.net 系统

20、可参考以下方法。在原有系统中进行数字签名(安全考虑),然后跳转到报表工程,将角色等信息以 t 方法传递过去。然后在报表工程中扩展一个 filter 进行数字签名认证。具体做法:把功能树的 url全部转到一个 jsp,将要的报表地址最为参数传递过去。在 jsp 中处理过后再跳转到报表 filter。在 jsp 作如下处理:1.根据 ses中保存的角色和报表名去数据库中验证,此角色是否可以该报表。如果验证失败则返回错误页面提示没有权限。2.3.取当前角色和当前系统时间进行数字签名。为安全起见将签名信息,过期时间,角色通过隐藏域表单自动提交到报表工程的 filter。在报表的 filter 中进行数

21、字签名认证,认证通过可以面提示错误信息。,失败到错误页下面以现有工程为例详述步骤:将 url 该为跳转到一 jsp 页面进行处理: HYPERLINK http:/w/ http:/w即把上图的风险Sign.jsp 中的代码/forumimages/f-risk warning.jpg的 url 改为 sign.jsp?reportlet=”报表名称”。form name=myform id=myform method=taction=/WebReport/ReportServer?reportlet=input type=hiddenname=time value=input type=hi

22、ddeninput type=hiddenname=role value=name=bytes value=.myform.submit();该页面会自动跳转到 form 中的 action,即跳转到报表工程下。代码中用到的方法:checkAuthority(name,role)publiccheckAuthority(String name,String role)flag = false;Connection conn = null; PreparedSement ps = null;ResultSet rs = null;try /sql:根据角色与报表名称查询数据库 该角色是否对应有此

23、报表的权限,/如果查出,表明可以,返回trueString sql = SELECT pathurl,path.pathid FROM path,role,role_pathWHERE role.roleid IN(+role+) AND role_path.pathid=path.pathidrole_path.roleid=role.roleid AND pathurl=+name+;ANDconn ps =rs = DBHelp.getConnection();conn.prepareSement(sql);ps.executeQuery();if(rs.next() flag = tr

24、ue; catch (Exception e) e.prStackTrace();return flag;本例采用 DSA 进行数字签名:其中生成公钥和私钥方法 generatorKeyPair()方法。public void generatorKeyPair() KeyPairGenerator keys = null; ObjectOutputStream out = null; FileOutputStream fos = null; try keys = KeyPairGeneratetInstance(DSA); SecureRandom random = new SecureRan

25、dom(); keys.initialize(keySize, random); /keySizeKeyPair keyPair = keys.generateKeyPair();= 512;PrivateKey priKey = keyPair.getPrivate(); /生成私钥PublicKey pubKey = keyPair.getPublic(); /生成公钥/将生成的私钥和公钥写入文件fos = new FileOutputStream(pri.dat); out = new ObjectOutputStream(fos); out.writeObject(priKey);ou

26、t.flush();fos = new FileOutputStream(pub.dat); out = new ObjectOutputStream(fos); out.writeObject(pubKey);out.flush(); catch (Exception e) e.pr finallytry oStackTrace();lose();fos.close(); catch (IOException e) e.prStackTrace();sign(signparam)方法:私钥,实际操作可以只一次后放入内存中。public String sign(String msg) Obje

27、ctInputStream in = null; FileInputStream fis = null; String encode = ;try /私钥fis = new FileInputStream(pri.dat); in = new ObjectInputStream(fis);PrivateKey priKey = (PrivateKey)in.readObject();in.close();/对数据进行签名Signature signature = Signature.getInstance(DSA); signature.initSign(priKey); signature.

28、update(msg.getBytes();byte bytes = signature.sign();/将签名后的数据转为string,方便传参encode = new String(Codecs.base64Encode(bytes), UTF-8);/需要额外的类,将签名后的字节数组转为string,查看该类 catch (Exception e) e.pr finallytry StackTrace();in.close();fis.close(); catch (IOException e) e.prStackTrace();return encode;下面介绍一下在报表工程中增加的

29、 filter:首先在打开报表工程的 web.xml,在里面加上需要增加的 filter 节点: HYPERLINK http:/w/ http:/w/forumimages/f-filtanel po.jpg下面就是要写 AuthorityFilter 类:public void doFilter(ServletRequest req, ServletResponseresp,FilterChain chain) throws IOException, ServletException HttpServletRequest request = (HttpServletRequest)req;

30、 HttpServletResponse response = (HttpServletResponse)resp;String report= request.getParameter(reportlet);if(report != null)String role = request.getParameter(role); /获取角色/将角色存入sesrequest.getSes,后面报表中需要用到().setribute(fr_authority,role);String time = request.getParameter(time); /获取过期时间if(time = null)/

31、如参数中没有,说明request.setribute(errormsg,对不起!您没限该报表!);request.getRequestDispatcher(error.jsp).forward(request, response);return;long outtime = Long.valueOf(time); /将时间转为long类型long nowtime = System.currentTimeMillis(); /获取当前时间if(outtimenowtime) /将传过来的过期时间与当前时间比较request.setribute(errormsg,对不起!您的已过期!);reque

32、st.getRequestDispatcher(error.jsp).forward(request, response);return;String bytes = request.getParameter(bytes); /获取签名后文件 String signparam = role + “&”+ time;flag = verify(signparam ,bytes);if(!flag)/进行签名信息request.setribute(errormsg,对不起!您没request.getRequestDispatcher(error.jsp).限报表!);forward(request

33、, response);return;chain.doFilter(request, response);verify(signparam ,bytes)方法:这里读公钥在实际操作中同样应该可以先public出放入内存,不需要每次进行verify(String msg,String signedBytes)flag = false;ObjectInputStream in = null; FileInputStream fis = null; try /读公钥fis = new FileInputStream(pub.dat); in = new ObjectInputStream(fis);

34、PublicKey pubKey = (PublicKey)in.readObject();/将签名文件转为byte类型byte bytes = Codecs.base64Decode(signedBytes.getBytes(UTF-8);/用到额外的类进行转换,查看该类Signature sign = Signature.getInstance(DSA); sign.initVerify(pubKey); sign.update(msg.getBytes(); if(sign.verify(bytes)flag = true; catch (Exception e) e.pr finall

35、ytry StackTrace();fis.close();in.close(); catch (IOException e) e.prStackTrace();return flag;写好类后,把它编译成 class 文件,然后把 class 文件放到报表工程文件夹下面,具体位置见下图:由于例子中的 filter的包是 com.fr.filter,所以在classes 文件夹下面新建了com/fr/filter 文件夹,把编译好的 class 文件放在 filter 文件夹下面,重新启动服务器就可以了。 HYPERLINK http:/w/ http:/w/forumimages/f-new

36、 folder.jpg转换字符用到的类:class Codecs private Codecs() public sic final byte base64Encode(byte abyte0) if (abyte0 = null) return null;byte abyte1 = new byte(abyte0.length + 2) / 3) * 4; i = 0;j = 0;for (; i abyte1j+ = Base64EncMapabyte0i + 1| abyte0i 0 x3f;4 & 0 xf6 & 3| abyte0i + 1 2 & 0 x3f;abyte1j+ =

37、Base64EncMapabyte0i + 2 & 0 x3f;if (i 2 & 0 x3f;if (i 4 & 0 xf| abyte0i 4 & 0 x3f;abyte1j+ = Base64EncMapabyte0i + 1 2 & 0 x3f; else abyte1j+ = Base64EncMapabyte0i 4 & 0 x3f;for (; j abyte1.length; j+) abyte1j = 61;return abyte1;public sic final byte base64Decode(byte abyte0) if (abyte0 = null) retu

38、rn null;i;for (i = abyte0.length; abyte0i - 1 = 61; i-);byte abyte1 = new bytei - abyte0.length / 4;for (j = 0; j abyte0.length; j+)abyte0j = Base64DecMapabyte0j;k = 0;l;for (l = 0; l abyte1.length - 2; l += 3) abyte1l = (byte) (abyte0k & 3);abyte1l + 1 = (byte) (abyte0k + 1 2 & 0 xf);abyte1l + 2 =

39、(byte) (abyte0k + 2 6 & 0 xff | abyte0k 3 & 0 x3f);k += 4;if (l abyte1.length)abyte1l = (byte) (abyte0k & 3);if (+l abyte1.length)abyte1l = (byte) (abyte0k + 1 & 0 xf);4+42returnabyte1;private s private sic byte Base64EncMap;ic byte Base64DecMap;sic byte abyte0 = 65, 66, 67, 68, 69, 70, 71, 72, 73,

40、74,75,76,77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,89, 90, 97, 98, 99,100, 101, 102, 103, 104, 105,106, 107, 108, 109, 110, 111,112, 113, 114, 115,116, 117, 118, 119, 120, 121, 122, 48, 49,50,51, 52, 53, 54, 55, 56, 57, 43, 47 ;Base64EncMapBase64DecMap= abyte0;= new byte128;0; i Base64EncMap.le

41、ngth; i+)for (i =Base64DecMapBase64EncMapi = (byte) i;报表中的权限管理控制上面所述是用现有的权限管理系统控制不同权限角色可以不同的报表,有时还需要在同一张报表中针对不同角色用户显示不同内容,下面就介绍有关这方面的例子。假设使用 ratio.cpt 这张报表,这张报表在安装文件夹下面,路径是:FineReport6.5WebReportWEB-INFreportletsdocTutorialadvancedCaculate_Bet n_Cellsratio.cpt这张报表正常时的效果如下:可以看到一至十二月份的统计数据 HYPERLINK h

42、ttp:/w/ http:/w/forumimages/f-normal visit.jpg一. 在 SQL 语句中应用权限参数假如数据库中存在三种角色,admin/sale/finance,现在需求所有角色都能看到这张报表,但是需要 admin 角色可以看到全部的,其他角色只能看到 1-6 月份的数据,要实现这样功能,可以从 sql 语句入手,根据不同的角色,显示不同的 sql,具体情况如下:SELECTMONTH(SIGNDATE) AS MONTH,ORDERID,AMOUNT FROMORDERS $if(fr_authority=R001, where MONTH(SIGNDATE)

43、=6)解释:SELECTMONTH(SIGNDATE) AS MONTH,ORDERID,AMOUNTFROM ORDERS 这个是原来的 sql,后面是加了 if 条件判断,fr_authority 是报表中内置的权限参数,R001 这里指的是管理员角色,这个角色是放在ses作用域中,这里是在权限过滤器中把角色信息放在 ses中(详情)(注意,此角色名 fr_authority 不可以通过 url 传递,解释)。在报表中通过 if 公式都可以得到角色的值,这里 R001 对应的是管理员,这个判断式意思为:如果角色为 R001,不加查询条件,否则加上 1-6 月份的查询条件,从而达到目的。在系

44、统中如果用管理员角色登录可以看到所有月份信息: HYPERLINK http:/w/ http:/w/forumimages/f-admin login.jpg如果换一个角色登录,则只能看到 1-6 月份的数据,如下所示: HYPERLINK http:/w/ http:/w/forumimages/f-normal login.jpg这样就实现了用 sql 语句控制不同的权限展示。二. 在报表设计中应用权限参数。1.权限控制控件比如现在有一个可以填报的报表,但是限制只有管理员可以填报,其他角色的人登录上来只能浏览。报表中是通过 参数 op=write 来控制是否是填报的,这样安全性比较低,可

45、以在需要填报的单元格上通过条件属性控制是否把该控件显示给用户,从而达到填报的目的,具体操作如下。例子中使用 additionDeletion.cpt 这张模板,该模板所在位置:FineReport6.5WebReportWEB-INFreportletsdemoformadditionDeletion.cpt 目录下,这是一个填报模板,开始效果如下: HYPERLINK http:/w/ http:/w/forumimages/f-initial result.jpg在客户的那一列是可以填报修改的,如果需求是只能管理员可以修改客户户这一列,而其他用户角色登录上来不可以修改。现在做法是:在模板的

46、客那列数据单元格 B5 上,添加一个条件属性,选择要改变的属性是控件,使用该控件条件是公式 $fr_authority=”R001”成立,即管理员(这个 R001 就是对应例子中管理员的角色,详情)。具体设置如下: HYPERLINK http:/w/ http:/w/forumimages/f-setup.jpg设置好以后放到该控件。自己的应用中,如果以不同角色登录就会区分是否显示如果以管理员角色登录,照常可以修改: HYPERLINK http:/w/ http:/w/forumimages/f-admin login2.jpg如果以 sale 角色登录(非管理员角色),则不可以修改客户那

47、一列,如下: HYPERLINK http:/w/ http:/w/forumimages/f-normal login2.jpg2权限控制内容显示这张报表中后面是可以增加删除的,有个增加删除的按钮。如果需求只有管理员可以增加修改,其他角色不可以增加修改,可以通过条件属性设置非管理员角色看到该列宽为 0.即达到隐藏该列的目的。在增加删除按钮单元格上增加条件属性,选择列宽为 0,条件使用公式:$fr_authority!=”R001”。其中 R001,为管理员角色,在报表过滤其中有设置,详情。具体如下: HYPERLINK http:/w/ http:/w/forumimages/f-conditional attribute.jpg这样设置过后,如果以管理员角色登录正常显示,可以看到增加删除两排按钮。 HYPERLINK http:/w/ http:/w/forumimages/f-admin login3.jpg如果以 sale 角色登录这两排按钮则隐藏了。 HYPERLINK h

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论