有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java访问控制器的使用

我正在努力理解java安全性和AccessController的基础知识。doPrivileged()用法 我从一个示例程序开始

import java.security.AccessController;
import java.security.PrivilegedAction;
public class AccessSystemProperty {
   public static void main(String[] args) {
     System.out.println(System.getSecurityManager());
       AccessController.doPrivileged(
        new PrivilegedAction<Boolean>(){
           public Boolean run(){
               System.out.println(System.getProperty("java.home"));
               return Boolean.TRUE;
           }
        }
       );
   }
}

如果我尝试使用默认的安全管理运行上述代码,我将获得AccessControlException 我的跟踪是

C:\>java -Djava.security.manager AccessSystemProperty
java.lang.SecurityManager@923e30
Exception in thread "main" java.security.AccessControlException: access denied (
java.util.PropertyPermission java.home read)
        at java.security.AccessControlContext.checkPermission(Unknown Source)
        at java.security.AccessController.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPropertyAccess(Unknown Source)
        at java.lang.System.getProperty(Unknown Source)
        at AccessSystemProperty$1.run(AccessSystemProperty.java:9)
        at AccessSystemProperty$1.run(AccessSystemProperty.java:8)
        at java.security.AccessController.doPrivileged(Native Method)
        at AccessSystemProperty.main(AccessSystemProperty.java:6)

请帮我弄清楚

1)当我们需要使用AccessController时。doPrivileged()?(如果存在SecurityManager,我们将使用AccessController.doPrivileged-为什么在上面的示例中失败)

2)使用AccessController和PrivilegedAction的真正优势是什么

3)上述示例是否需要自定义策略文件才能工作

谢谢

保罗


共 (1) 个答案

  1. # 1 楼答案

    您将使用AccessController。doPrivileged()为调用堆栈中早期的代码授予某些代码特权,这些代码不具有这些特权,但由于在策略中授予了这些特权,这些特权代码确实具有这些特权

    例如,假设ClassA调用ClassB上的方法,ClassB需要读取java。主系统属性(借用您的示例),并假设您已指定SecurityManager与您的示例相同

    还假设ClassB是从名为“ClassB.jar”的jar加载的(但为了使示例工作,ClassA不是从该jar加载的),安全策略文件中应包含以下内容:

    grant codeBase "file:/home/somebody/classb.jar" { 
        permission java.util.PropertyPermission "java.home", "read";
    };
    

    现在,当ClassB运行并尝试运行系统时。未包装在AccessController中的getProperty()。“java.home”上的doPrivileged()。安全管理器将检查堆栈,以查看堆栈上较高的每个类是否都具有“java.home”的PropertyPermission(无论是直接的还是隐含的)。否则,访问将失败

    但是,如果ClassB包装了系统。AccessController中的getProperty()。doPrivileged()securitymanager只关心策略文件是否赋予ClassB该权限,从而允许访问

    下面是一个片段来说明这一点:

    public void doStuff() {
    
        try {
            /*
             * this will fail even if this class has permission via the policy file
             * IF any caller does not have permission
             */
            System.out.println(System.getProperty("java.home")); 
        } catch (Exception e1) {
            System.out.println(e1.getMessage());
        }
        AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
            public Boolean run() {
                try {
                    /*
                     * this will be allowed if this class has permission via the policy
                     * file even if no caller has permission
                     */
                    System.out.println(System.getProperty("java.home"));
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
    
                return Boolean.TRUE;
            }
        });
    

    因此,在您的示例中,您只需要指定一个策略文件,其中包含类似于我上面提到的grant节的内容