2

想象这样的事情:

import class B.*;


interface A supports A.testSum
{
   int sum( int a , int b ) access from B.calculator;

   testSum() { Assert(sum(1,1)==2); }

........


class B ...
{
  void calculator() {  A.sum(3,5); //ok }
  void someOtherMethod() { A.sum(0,3); //compile error }

“支持”的想法是次要的但相关的,因为在这种情况下测试适用于接口(因此语言将区分所有实现必须通过的接口测试和特定于实现私有的实现测试

但我想在这里传达的重要思想是访问控制语义;请注意,带有“access from”关键字的 A.sum 只能从方法 B.calculator 中调用。其他任何东西都被检测为编译时错误。这里的想法是以更细化的方式实施架构约束。如果您没有添加“访问自”或仅添加“访问自 *”,则意味着允许从任何地方调用该方法的默认行为。什么样的架构约束?好吧,在进行分层设计时手动执行的那种:A层(最低层)从B层(中间层)使用,而B层又从C层(高层)使用。但是 A 层无法访问 B 层,A 或 B 都无法访问 C 层,

问题:你知道支持上述语义的任何语言(包括源到源中间语言)吗?讨论这种语义是否会适得其反、危险或只是鼓励不良设计的额外要点

更新:这种限制还有另一个非常重要的用例:

事件驱动编程:通常事件的问题是事件往往做的太多,理解事件的依赖链可能会变得很棘手

因此,例如,可以定义事件处理程序只有一组可以交互的可见类(或者相反,它不能接触的一组对象)

4

3 回答 3

2

这听起来像是对象能力模型的一个特例。也许有些语言以某种方式实现了这一点。

同样,快速搜索“方法级安全性”让我发现了一些企业 Java 社区似乎已经准备好的东西。我认为将这种方法专门用于方法调用是毫无意义的。除非您有充分的理由这样做,否则我认为这可能是个坏主意。如果您出于某种原因真的有兴趣这样做,那么模型应该是让接收者检查调用源是否在某个允许的集合中。

无论如何,这基本上严重破坏了大多数编程模型。最好强制执行前提条件和类不变量,以确保任何方法调用(从任何地方!)都是有意义的或行为良好的。如果您使用它来强制执行方法排序,则可以使用不变检查(静态或在运行时)或诸如Interface Automata之类的理论模型来实现。

于 2010-08-15T15:30:57.867 回答
1

Java 支持的东西几乎相同。

首先,字段和方法的可见性是在运行时强制执行的,非特权代码不可能绕过这一点。

您还可以创建自己的权限,并将它们授予代码的某些部分。例如,要打开一个文件,想要访问该文件的代码需要FilePermission该文件。但是,您可以进行任何您希望的权限,也可以在求和之前创建一个名为SumPermissionwhichCalculator检查的权限,并且只将其授予您想要的任何类。保护域跨越类,而不是类中的单个方法,因为整个类通常是从单一来源获得的。该模型实际上比您提出的更深入。导致安全检查的堆栈上的每个类(包括线程创建的历史)都必须具有权限,因此如果某些不受信任的代码调用您的代码SumPermission,它将无法通过安全检查。当然,这只是默认设置,每当你做任何需要权限的事情时,你都可以使用一个doPrivileged块来告诉即将进行的检查只检查你的权限,而不是你和你的调用者的权限。

但是,Java 中当前的默认安全方案有很多限制。一方面,不受信任的代码不能细分其权限或为嵌套的不受信任代码定义自己的权限。此外,防止不受信任的代码阻塞也很痛苦。

您可能想查看E。特别是,它遵循对象能力模型。它是为相互不信任的代码安全交互而设计的,并且具有语言级别的结构来防止死锁问题。

It's perfectly possible and feasible to implement robust behavior between mutually untrusted code in Java, but E will probably make your job much easier, and runs on the JVM so you should still be able to use Java libraries and libraries from any other languages that use the JVM.

于 2010-09-06T16:38:03.587 回答
0

这在 Ruby 中是可行的,尽管语法不同。采取以下措施:

module T
    def check
        raise unless self.is_a?(Ca)
        raise unless %r{in `good_func'} =~ caller.first #`
        true
    end
end

class Ca
    include T
    def good_func
        check
    end
    def bad_func
        check
    end
end

class Cb
    include T
    def good_func
        check
    end
    def bad_func
        check
    end
end

a = Ca.new
b = Cb.new

a.good_func
=> true
a.bad_func
=> (RuntimeError)

b.good_func
=> (RuntimeError)
b.bad_func
=> (RuntimeError)

当使用模块作为混入时,self对应于include模块的类。 caller返回当前调用堆栈,并caller.first为您获取调用堆栈上的第一个条目(即调用此条目的函数)。

于 2010-08-11T20:22:18.063 回答