动态Proxy与Java ACL用户会见节制机制实现
当前位置:以往代写 > JAVA 教程 >动态Proxy与Java ACL用户会见节制机制实现
2019-06-14

动态Proxy与Java ACL用户会见节制机制实现

动态Proxy与Java ACL用户会见节制机制实现

副标题#e#

用户会见节制(Access control )机制老是环绕粗粒度和细粒度两个方面来接头:

粗粒度节制:可以划定会见整个工具或工具群的某个层,而细粒度节制则老是在要领或属性层举办节制,好比:

答允一个文件为只读是属于粗粒度节制,而答允对这个文件某行有写操纵则属于细粒度节制。

一个好的用户节制机制虽然既答允粗粒度也答允细粒度节制,在Jive中我们看到是利用Proxy来到达这个目标,可是我们也发明,由于需要对每个类都要举办细粒度节制,所以一定对每个类都要做一个Proxy类,这样带来了许多Proxy类,如ForumProxy ForumThreadProxy ForumFactoryProxy等,无形增加了系统巨大性。

利用动态Proxy可以很好的办理这个问题。再团结java.security.acl的ACL机制,我们就可以机动地实现粗粒度和细粒度的双重节制。

当一个用户login后,我们就要在内存中为其成立相应的授权会识趣制,利用java.security.acl可以很利便的成立这样一个安详系统。

首先任何一个工具都应该有个根基属性:拥有者 或拥有者所属组(Windows中每个目次安详描写符都由4部门组成:工具的建设者、工具所属的组、自由存取节制和系统存取节制)。

1. Java acl开始第一步是成立一个主体 Principal,个中SecurityOwner是主体的拥有者: private static final Principal _securityOwner = new PrincipalImpl("SecurityOwner");

2. 当用户login进来时,他带有两个根基数据:会见暗码和他要会见的工具ApplicationName。首先验证用户名和暗码,然后从数据库中取出其权限数据,成立Permission,这里利用Feature担任了Permission,在Feature中界说了有关权限的细节数据(如读 写 删)。

// 取出用户和被会见工具之间的权限干系,这种权限干系大概不但一个,也就是说,用户

//大概对被会见工具拥有读 写 删等多个权限,将其打包在Hasbtable中。

Hashtable features = loadFeaturesForUser(sApplicationName, sUserID);

3. 建设一个用户工具

User user = new UserImpl(sUserID, new Hashtable() );

4. 为这个用户建设一个勾当的acl entry

addAclEntry( user, features);

个中最要害的是第四步addAclEntry,我们看看其如何实现的:

// 为这个用户建设一个新的Acl entry
AclEntry newAclEntry = new AclEntryImpl( user);
   //遍历Hashtable features,将个中多种权限插手:
....
feature = (Feature) hFeatures.get(keyName);
newAclEntry.addPermission( feature );
....

最后也要插手主体拥有者SecurityOwner

这样一个安详体系就已经成立完成。

当你在系统中要检讨某个用户利用拥有某个权限,如读的权利时,只要

acl.checkPermission(user, feature )就可以,acl是ACL的一个实例,这样权限查抄就交给

java.security.acl.ACL 去处理惩罚了。


#p#副标题#e#

有了ACL机制后,我们就可以在我们系统中利用动态Proxy模式来对详细工具或要领举办节制,好比,我们有一个Report类,有些用户可以读,有些用户可以写(哪些用户可以读 哪些用户可以写,已经在上面ACL里陈设完成)。

从Java 1.3开始, Sun提供了Dynamic Proxy API.为了使动态Proxy可以或许事情,第一你必需有一个Proxy接口,还要有一个担任InvocationHandler的Proxy类。

在下面的例子中,我们设定有三种用户:普通人;雇员;司理.权限是这样:普通人可以读陈诉;雇员和司理可以修改陈诉。

按凡是思维,我们对付读权限,我们设计一个具备读的脚色类:

public interface IpersonRO {
public String getName();
public String getAddress();
public String getPhoneNumber();
}

类内里都是读的要领,这是一种粗粒度会见节制,也就是说把读写权限只落实到类(工具)上,这样的话,我们还要为写的脚色再建一个类,很显然这不是一个很好的要领,利用动态proxy+acl就可以实现很好的细粒度节制。

public class ReportProxy implements InvocationHandler
{
   private Map map;
public static Object newInstance(Map map,Class[] interfaces)
{
return Proxy.newProxyInstance(map.getClass().getClassLoader(), interfaces,new ReportProxy(map));
}
   public ReportProxy(Map map)
{
this.map = map;
}
   public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
{
Object result;
String methodName = m.getName();
if (methodName.startsWith("get"))
{
if (!acl.checkPermission(user, "read")) return null;
String name = methodName.substring(
methodName.indexOf("get")+3);
return map.get(name);
}
else if (methodName.startsWith("set"))
{
if (!acl.checkPermission(user, "write")) return null;
String name = methodName.substring(
methodName.indexOf("set")+3);
map.put(name, args[0]);
return null;
}
else if (methodName.startsWith("is"))
{
if (!acl.checkPermission(user, "read")) return null;
String name = methodName.substring(
methodName.indexOf("is")+2);
return(map.get(name));
}
return null;
}
}

    关键字:

在线提交作业