AccessController usage

2019-03-12 00:25发布

问题:

I am trying understand the basics of java security and AccessController.doPrivileged() usage I started with a sample program

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;
           }
        }
       );
   }
}

if I try to run above code using default security manage I am getting AccessControlException My stacktrace is

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)

Kindly help me to get a clear picture of

1) When we need to use AccessController.doPrivileged()? (if SecurityManager is present we use AccessController.doPrivileged - why this is failing in above example)

2) What is the real advantage we are getting by using AccessController and PrivilegedAction?

3) Do we need custom policy file for above example to work?

Thanks,

Paul

回答1:

You would use AccessController.doPrivileged() to give certain code privileges that code earlier in the calling stack DOES NOT have but which the privileged codes DOES have by virtue of that privilege being granted in a policy.

For example, assume ClassA invokes methods on ClassB, and ClassB needs to read the java.home system property (to borrow from your example), and assume that you've specified that SecurityManager is present as per your example.

Also assume that ClassB is loaded from a jar named "classb.jar" (but to make the example work ClassA is NOT loaded from that jar), the following should be in the security policy file:

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

Now when ClassB runs and tries to do a System.getProperty() which is NOT wrapped in an AccessController.doPrivileged() on "java.home". the security manager will check the stack to see if every class higher on the stack has PropertyPermission (whether directly or implied) for "java.home". If not, the access will fail.

However, if ClassB wraps the System.getProperty() in an AccessController.doPrivileged() the securitymanager only cares that the policy file gives ClassB that privilege and so the access is allowed.

Here's a fragment to show this:

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;
        }
    });

So in the case of your example, you just need to specify a policy file containing something similar to the grant stanza that I referenced above.



标签: java security