Struts,ZK 各实现细粒度的权限验证控制(上)

      权限控制我们有很多种实现的方法,而对于不同的UI编程不同的开源框架,都能各施其法
 比如说有像Struts 中需要细粒度的控制到按钮级别的权限,我们可以使用url拦截过滤来实现权限验证功能.而比如使用ZK框架的时候我们就发现URL拦截器不在适合这种环境了,ZK是一个与一些我们比较熟知的Ext,JSF Web框架一样的Ajax框架.他们的共同点是基于组件,能快速方便的实现对UI设计.

 

       ZK 是一个事件驱动(dvent-driver),基于组件(component),是处理用户活动而引发的事件.ZK处理用户请求分两个阶段,一个是url请求的,一个是Zk Client Engine 发送的请求,

       1.用户第一次请求时,是一个URL Request,由zk Loader Servlet处理,对应web.xml中的 org.zkoss.zk.ui.http.DHtmlLayoutServlet

        2.响应客户页面以后,ZK AU Engine与 Zk Client Engine交互,如果不调用(sendRedirect),那么都是事件驱动
当用户点击一个按钮时,首先,ZK Client Engine获得这个事件,然后ZK Client Engine发送这个事件到服务器Zk AU Engine,这个数据格式是类json格式.Zk AU Engine接收到这个事件,加入到事件队列,ZK AU Engine处理队列里的事件,然后将出列结果返回给ZK Client Engine.ZK Client Engine处理服务器响应,如果发现需要更新页面 Zk Client Engine更新页面组件Zk使用两个不同的Servlet处理.

       针对这两个完全不同实现的框架可以采用不同的权限验证方法.
一、Struts 的页面交互是通过url请求提交给相应的Action类来处理
  我们可以采用 Filter 过滤机制

  拦截 url 做权限判断

对于 web 系统,权限表有这么几个字段:标识、名称、描述、对应 url 。
那么对于 url 请求,可以在权限表进行查找,查看该 url 是否有个对应的权限。如果有,说明该 url 需要具有没个权限才能访问,那么通过 RBAC 算法进行判断即可。如果在权限表没有找到对应记录,说明该 url 不需要进行权限验证。

该需求比较简单,也可以采用 Filter 机制,不妨取名 UrlAclFilter 。

唯一需要注意的地方是:权限表对应的 url 可能带有参数。比如 customreManager?op=add 是增加客户权限, customerManager?op=delete 是删除客户权限。

伪代码如下:

Java代码 
if( needPrivilegeCheck( request ) ) { 
// 需要做权限判断 
if( session.getAttribute( “user” ) ==null ) { 
// 用户还没有登录,转移到登录界面 
redirect( loginPage, request, response ); 
return; 
} else { 
if( userManager.hasPrivilege( user, privilegeId ) ) { 
filter.doChain( request, response ); 
return; 
} else { 
redirect( forbiddenHintPage, request, response ); 
return; 
} 
} 
} 

 


基础数据库表

权限表,该表基本有这么几个字段:标识、名称、描述、指向 url 、 target 。 target 表示点击该 Url 时在那个窗口显示。标识为主键。
比如下图所示 frameset ,权限菜单 target 属性应该是: MAIN

角色表,该表字段:标识、名称、描述;标识为主键。
权限-角色关系表,该表有字段:角色标识、权限标识;角色标识和权限标识为复合主键。
用户-角色关系表,该表有字段:用户标识、角色标识;用户标识和角色标识为复合主键。
===============================================================================


而ZK基于组件的权限验证我们可以使用以下实现方法

基础数据库表

权限表,该表基本有这么几个字段:ID主键、名称、描述 (对系统使用者而言我们可以授权下一级用户的权限,对应的角色有多少权限都在权限表中存下)

资源表 字段:Id主键、资源名称、资源类型(注:如button,menu)、对于整个系统的所有用到的资源集合这是固定不变的.(一个系统当需求确定下,所有的资源是固定的)


角色表  字段 Id主键、名称、描述、是否可删除(一个系统必须有一个超级管理员且无法删除)、  

权限-角色关系表,该表有字段:角色标识、权限标识;角色标识和权限标识为复合主键。
用户-角色关系表,该表有字段:用户标识、角色标识;用户标识和角色标识为复合主键。


当我们创建新用户时,将用户分配角色,再将对角色授权.这样我们的数据表结构就设计好了
下面是具体业务的实现:

  首先我们将需要用到的全局变量全部放在一个类中以便后期的维护.

package com.linktel.linkFax;

import com.linktel.linkFax.domain.User;
import com.linktel.linkFax.web.zk.util.ZkUtils;

public class LinkFaxContext {
public static final String CURRENT_USER = "user";
public static final String CURRENT_AUTHORITIESSTR = "authoritiesStr";
public static final String UPLOAD_LOGOS="/logos/";

public static User currentUser() {
return (User) ZkUtils.getSessionAttr(CURRENT_USER);
}
}

 

然后我们再创建一个初始化页面的类实现Initor 接口  (注:当我们实现了Initor接口后我们在页面绑定该类,在页面被加载的时候先会进入public void doInit(Page page, Map arg1) throws Exception {}方法   我们在init()方法中可以读取所有的角色对应的权限将它每个权限名称都以都分隔符隔开保存到一个String 字符串里(如:accesssCreateUser,accessAddUser,accessUpdateUser)再将拼接完的权限的集合保存到session中
(注:为什么要把所有的权限名称放到string中拼接而不是直接放入List或者Map集合中?答:请看下一篇,写不下了);

 

你可能感兴趣的:(框架,Web,UI,struts,zk)