OSGi R4服务平台核心规范 :第十章 权限管理服务规范

 由  满江红开放技术研究组织 发布

10.权限管理服务规范

版本号: 1.2

10.1.简介

在框架中,bundle都有一个单独的权限集合。通过使用这些权限来验证bundle是否具有对一些特权代码的执行权限。例如,一个FilePermission定义了使用哪个文件以及如何使用文件的方法。

对bundle的权限授予的执行应该交由管理代理(Management Agent)来实行。由于这个原因,框架提供了权限管理服务,这样,管理代理就可以对bundle的权限进行管理,而且可以给bundle赋予缺省的权限。

其他的框架相关机制在安全概要[P13]中进行了说明。

10.1.1.要点

  • 状态信息(Status information)– 权限管理服务必须要提供bundle的当前权限状态信息。
  • 可管理性(Administrative)– 权限管理服务必须要允许管理代理在bundle的安装之前、安装进行中和安装完毕之后都可以进行权限设置。
  • 缺省性(Defaults) – 权限管理服务必须提供对缺省权限的控制。这些是bundle不用指定而直接拥有的权限。

10.1.2.实体

  • PermissionAdmin – 提供了对框架权限库的访问的服务。
  • PermissionInfo – 保存了构造一个Permission类所需要的信息的类。
  • Bundle location – 描述了bundle的位置的字符串。在bundle标识符[81]一节中对它进行了详细描述。

10.1.3.操作

框架包括了一个权限库。这些权限使用了bunde的位置字符串来标识。使用bundle位置字符串可以允许在下载bundle之前对权限进行设置。当框架需要某个bundle的权限时,需要从这个库中获得该bundle的权限。如果没有设置这个bundle的权限,那么就必须使用缺省权限。如果没有设置缺省权限,那么就使用java.security.AllPermission中设置的权限。如果修改了缺省权限,那么必须要立即重新启动那些未设置权限的bundle,而且使用修改后的缺省权限。这是由于这些bundle使用了修改前的缺省权限。

框架的系统bundle通过接口the org.osgi.service.permissionadmin.PermissionAdmin来注册权限管理服务。这是一个可选的单态服务,因此,在任何时候都最多只有一个注册的权限管理服务。

权限管理服务提供了对权限库的访问。管理代理可以获得、修改、更新和删除从这个库中获得的权限。管理代理也可以通过使用同步bundle监听器(SynchronousBundleListener)对象,在安装和更新bundle的时候对bundle权限进行设置。

10.2.权限管理服务

权限管理服务需要操作缺省权限和指定bundle的相关权限。缺省权限和指定bundle的相关权限都是持久存储的。我们可以在安装bundle之前来设置bundle的权限,这是由于使用了bundle的位置字符串来设置bundle权限。

但是,对bundle的权限操作却有可能是实时的,这有可能在下载bundle的时候完成,甚至在下载之前就完成。为了支持这种适应性要求,在管理代理就需要使用一个同步bundle监听器对象(SynchronousBundleListener)来检测安装或者是更新一个bundle,同时也可以在安装完成之前就设置好bundle需要的权限。

在对bundle进行权限检查之前,权限就已经设置好的。这也就是说,如果一个bundle打开了一个文件,那么即使现在删除了bundle对这个文件的打开权限,但是bundle依然还是可以使用这个文件。

权限信息不是通过使用java.security.Permission来指定的。这是由于框架重新启动之后需要这些持久信息,以及框架的类加载器的机制的原因。实际的权限类(Permission)必须是Permission类的一个子类或者是可以从任一bundle中导出提供。在bundle导出之后,框架就可以访问这些权限了,而管理代理应该导入所有可能包含权限的包。这种需求将极大限制了权限的类型。因此,权限管理服务使用权限信息类(PermissionInfo)来指定权限的信息。框架使用这个类的实例来创建Permission对象。

权限信息对象限定了可能使用的权限(Permission)对象。一个Permission类的子类可以使用一个PermissionInfo对象来描述,这个Permission类的子类必须要满足以下特性:

  • 必须是java.security.Permission的一个子类。
  • 必须拥有带有两个参数的公有构造方法,形如type(name,actions)。
  • 框架代码必须可以通过系统类路径或者是导出包来使用这个类,这样框架就可以加载这个类。
  • 这个类必须是公有的。

如果不满足以上任意一个条件,那么忽略处理这个PemissionInfo对象,而且在日志中记录这个错误。

通常,将权限设置为一个PemissionInfo对象的数组,这样就可以自动的完成权限的赋值。

PermissionAdmin接口提供了以下方法:

  • getLocations() – 返回一个位置的列表,具有对这些位置的权限描述。管理代理使用这个方法来测试当前的权限集合。
  • getPermissions(String) – 返回PermissionInfo对象的列表,这些PermissionInfo对象具有对指定位置的权限,如果没有设置权限,那么返回null。
  • setPermissions(String,PermissionInfo[]) – 将权限和一个指定位置关联。或者如果应该移除这个权限,则返回null。
  • getDefaultPermissions() – 这个方法返回缺省缺陷列表
  • setDefaultPermissions(PermissionInfo[]) – 设置缺省权限。

10.2.1.相对路径名称的文件权限

通过setPermissions方法分配给bundle的一个java.io.FilePermission对象,如果这个FilePermission对象的路径参数是一个相对路径名称,那么必须要特殊处理这样的对象。相对路径名称不是绝对路径。可以参阅java.io.File.isAbsolute方法,获得更多的关于绝对路径名称的信息。

当给bundle分配一个带有相对路径名称的FilePermission对象时,在bundle的持久存储区中也是将这个路径看作是一个相对路径。这样允许附加的权限,例如分配了对bundle持久存储区中文件的执行权限。如下例:

  java.io.FilePermission "-" "execute"

这样允许bundle执行bundle持久存储区中的任何文件。

上述说明只是应用于通过setPermission方法来分配bundle的FilePermission对象。而不适用于缺省的权限。不考虑通过setDefaultPermission方法来设置的带有相对路径的FilePermission对象。

10.3.安全

权限管理服务是一个有缺陷的系统服务。具有访问和使用权限管理服务的bundle就可以对OSGi服务平台进行完全控制了。然而,很多bundle具有权限ServicePermission[PermissionAdmin, GET],这是由于所有的改变框架状态的方法都需要AdminPermission权限。

任何bundle都不能具有权限ServicePermission[PermissionAdmin,REGISTER],这是由于只有框架应该提供这样的服务。

10.4.更改

下面描述的是由于和原来发布的版本的相关内容:

  • 对权限信息(Permission Info)进行了更新,在编码格式中允许使用空格。
  • 修改权限的包管理方法需要调用者具有AllPermission权限。由于如果只有一个简单指定的权限就可以修改bundle的权限,那么将会导致对bundle权限提升,甚至可以提升到AllPermission。

10.5.org.osgi.service.permissionadmin

OSGi权限管理服务包,版本规范:1.2。

需要使用这个包的bundle必须要导入这个包,通过在bundle清单文件中的Import-Package头标中描述。例如:

   Import-Package: org.osgi.service.permissionadmin; version=1.2

10.5.1.概要

  • PermissionAdmin – 权限管理服务允许管理代理来对bundle的权限进行管理。[p.248]
  • PermissionInfo – 权限管理服务中使用的权限的表示形式。[p.250]

10.5.2.public interface PermissionAdmin

权限管理服务允许管理代理来对bundle的权限进行管理。在OSGi环境中,最多只能有一个权限管理服务存在。

对权限管理服务的访问由ServicePermission权限来进行保护。另外设置权限时还需要AdminPermission。通过使用权限表来管理bundle的权限。将bundle的位置字符串用来作为权限表中的码。权限表的条目都是权限(类型为PermissionInfo)的集合,这些权限授予给名称为指定位置的bundle。在将bundle安装到框架中之前,bundle也可能在权限表中有一个条目。

通过setDefaultPermissions设置的权限可以当作缺省权限使用,将这些权限赋予给所有那些在权限表中没有条目的bundle。

在权限表中对bundle的任何权限修改将导致对bundle的java.security.ProtectionDomain进行权限检查,而且是持久性保存。

在权限检查时,只考虑在系统类路径中的权限类或者是从导出包中的权限类。另外,只能使用java.security.Permission类的子类,而且在这个子类中,定义了带有一个名称字符串参数和一个动作字符串参数的构造函数。

由框架授予的权限是不能修改的(例如,bundle对于它的持久存储区的访问权),而且也不会影响到getPermissions 和getDefaultPermissions返回的权限值。

10.5.2.1.public PermissionInfo[] getDefaultPermissions( )

 

获得缺省权限

对于没有通过位置字符串来定义权限的bundle,系统所授予的权限。

Returns

返回缺省权限,或者如果没有设置缺省权限,返回null。

10.5.2.2.public String[] getLocations( )

 

返回bundle的位置字符串,根据这个字符串来定义权限,也就是,用在权限表的条目中。

Returns

返回分配了任何权限的bundle的位置字符串,如果权限表中为空,返回null。

10.5.2.3.public PermissionInfo[] getPermissions( String location )

location

待返回权限的bundle的位置字符串

 

获得分配给指定位置的bundle的权限。

Returns

通过指定位置的bundle的权限,如果对于这个bundle没有分配任何权限,返回null。

10.5.2.4.public void setDefaultPermissions( PermissionInfo[] permissions )

permissions

缺省权限,或者为null,表示从权限表中删除缺省缺陷。

 

设置缺省权限。

这些权限是授予给那些没有通过位置字符串来分配权限的bundle。

Throws 

SecurityException – 如果调用者没有AllPermission权限。

10.5.2.5.public void setPermissions( String location, PermissionInfo[] permissions)

location

待设置权限的bundle的位置字符串

permissions

待设置的权限,或者如果删除指定bundle的权限,则为null。

 

给通过位置字符串指定的bundle分配指定权限。

Throws 

SecurityException – 如果调用者没有AllPermission权限。

10.5.3.public class PermissionInfo

权限管理服务中使用的权限表示形式。

这个类中封装了三部分信息:Permission类型(类名称),必须是java.security.Permission类的子类;从构造方法中传递过来的名称和操作参数。

为了实例化一个使用PermissionInfo表示的权限类,考虑在权限检查的时候,Permission必须是通过系统类路径或者是一个导出包来提供。这也就是说对一个通过PermissionInfo表示的权限实例有可能要等到直到bundle导出了包含Permission类的包。

10.5.3.1.public PermissionInfo( String type, String name, String actions )

type

这个PermissionInfo类的表示的权限类的类名称。

必须是java.security.Permission类的子类,而且必须定义了带有两个参数的构造方法,其中一个参数是一个名称字符串,另一个参数是一个操作字符串。

name

权限名称,将这个名称作为Permission类的构造方法的第一个参数。

actions

权限操作,作为Permission类的构造方法的第二个参数。

 

通过指定类型,名称和操作构造一个指定类型的PermissionInfo类。

Throws

NullPointerException – 如果类型为null。

IllegalArgumentException – 如果操作不为null而名称为null。

10.5.3.2.public PermissionInfo( String encodedPermission )

encodedPermission

编码的PermissionInfo

 

从指定编码的PermissionInfo字符串中构造一个PermissionInfo类。不考虑编码中的空格。

Throws

IllegalArgumentException – 如果encodedPermission的格式不正确。

See Also

getEncoded[p.251]

10.5.3.3.public boolean equals( Object obj )

obj

和这个PermissionInfo类进行相等比较的类

 

确定这两个PermissionInfo类是否相等。这个方法检查指定类是否和这个类具有相同的类型、名称、和操作。

Return

如果obj是一个PermissionInfo类,而且具有相同的类型、名称、和操作,那么返回true。否则返回false。

10.5.3.4.public final String getActions( )

 

返回这个PermissionInfo表示的权限的操作。

Return

这个PermissionInfo表示的权限的操作,如果这个权限没有关联任何操作,返回null。

10.5.3.5.public final String getEncoded( )

 

返回这个PermissionInfo类的编码字符串。编码格式如下:

(type)

或者

(type “name”)

或者

(type “name” “actions”)

其中的名称和操作的编码采用语法分析。其中换行符分别使用\”,\,\r和 \n来转义。

在编码中没有起始和结尾的空格,在类型和“name”以及“name”和“action”之间使用一个空格分隔。

Return

PermissionInfo类的编码字符串。

10.5.3.6.public final String getName( )

 

返回这个PermissionInfo表示的权限的名称。

Return

这个PermissionInfo类表示的权限的名称,或者如果这个权限没有名称,返回null。

10.5.3.7.public final String getType( )

 

返回这个PermissionInfo表示的权限的全局类名称。

Return

这个PermissionInfo表示的权限的全局类名称。

10.5.3.8.public int hashCode( )

 

返回这个类的哈希码

Return

这个类的哈希码

10.5.3.9.public String toString( )

 

返回这个PermissionInfo表示的字符串。通过调用getEncoded方法来创建这个字符串。

Return

表示这个PermissionInfo类的字符串。

查看评论