Access control in Java -- doPrivileged

  sonic0002        2016-03-08 05:46:42       4,403        0    

Previously we have introduced how Java performs permission check to protect resource access. What if sometimes we need to give some class the temporary access to some resource which it initially doesn't have? AccessController provides six doPrivileged methods to fulfill this requirement.

These six methods have below signatures :

static T doPrivileged(PrivilegedAction action)
static T doPrivileged(PrivilegedAction action, AccessControlContext context)
static T doPrivileged(PrivilegedExceptionAction action)
static T doPrivileged(PrivilegedExceptionAction action, AccessControlContext context)
static T doPrivilegedWithCombiner(PrivilegedAction action)
static T doPrivilegedWithCombiner(PrivilegedExceptionAction action)

Basically based on the parameters passed in, there are two category of actions : PrivilegedAction and PrivilegedExceptionAction. The difference between them is that PrivilegedAction will not throw a PrivilegedActionException even if there is a checked exception thrown in the run() method while PrivilegedExceptionAction will throw PrivilegedActionException.

A caller can be marked as being "privileged" (when doPrivileged() called). When making access control decisions, the checkPermission method stops checking if it reaches a caller that was marked as "privileged" via a doPrivileged call without a context argument. If that caller's domain has the specified permission, no further checking is done and checkPermission returns quietly, indicating that the requested access is allowed. If that domain does not have the specified permission, an exception is thrown, as usual.

For example, we have below calling stack :

at protectiondomain.a.A.test0(A.java:12)
at protectiondomain.a.A.test(A.java:6)
at protectiondomain.b.B.test(B.java:9)
at AccessTest.main(AccessTest.java:7)

AccessTest is in System Domainprotectiondomain.b.B is in protection domain http://b.test.com and protectiondomain.a.A is in protection domain http://a.test.com. In protectiondomain.a.A.test0(), there is a call to System.getProperty("os.name"). When SecurityManager is turned on, the method call System.getProperty("os.name") will internally invoke a permission check to see whether the calling class protectiondomain.a.A has the proper read permission of the system property os.name

Now assuming that protection domain http://b.test.com doesn't have the permission to read property os.name. Then the permission check will fail when System.getProperty("os.name") is called in protectiondomain.a.A.test0(). But if you surround the System.getProperty("os.name") with doPrivileged() method, the permission check will stop at domain http://a.test.com and  hence the permission check will succeed.

Note that checkPermission always performs security checks within the context of the currently executing thread. Sometimes a security check that should be made within a given context will actually need to be done from within a different context (for example, from within a worker thread). If an AccessControlContext is passed into the doPrivileged Method, then the protection domains of the AccessControlContext will also be checked about their permissions.

If we create a AccessControlContext with below code :

private static final AccessControlContext NOPERMS_ACC ;

static {
    Permissions perms = new Permissions();
    ProtectionDomain[] pd = { new ProtectionDomain(null, perms) };
    NOPERMS_ACC = new AccessControlContext(pd);
}

If we pass this context to doPrivileged(), then it means no permission will be given because this context is created with no permission given. This means all codes called in this doPrivileged() will have to explicitly call doPrivileged() if they want to access resources requiring permission.

Note doPrivileged() will grant permission to the caller code but not the code it calls.

JAVA  SECURITY  DOPRIVILEGED 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

Cybertruck after many years