Sponsored Link •
|
Advertisement
|
doPrivileged()
It is important to understand that a method can never grant itself more privileges than it already has
with a doPrivileged()
invocation. By calling
doPrivileged()
, a method is merely enabling privileges it already has. It is telling
the AccessController
that it is taking responsibility for exercising its own
permissions, and that the AccessController
should ignore the permissions of its
callers. Thus, the doPrivileged()
call in the previous example,
Example2c
enabled answer.txt
to be read because
Friend
, the class that executed the doPrivileged()
, already
had permission to read the file, and so did all the frames above it on the stack.
For an example of a futile attempt to use doPrivileged()
, consider the
Example2d
application from the security/ex2
directory of
the CD-ROM:
// On CD-ROM in file security/ex2/Example2d.java import com.artima.security.friend.Friend; import com.artima.security.stranger.Stranger; // This fails because even though Stranger does // a doPrivileged() call, Stranger doesn't have // permission to read question.txt. (Passing // false as second arg to Stranger constructor // causes it to do a doPrivileged().) class Example2d { public static void main(String[] args) { TextFileDisplayer tfd = new TextFileDisplayer("answer.txt"); Stranger stranger = new Stranger(tfd, false); Friend friend = new Friend(stranger, true); friend.doYourThing(); } }
The difference between Example2d
and the previous example,
Example2c
, is that the Stranger
and
Friend
objects have swapped positions and roles. The
Stranger
object is now farther up the stack, with the Friend
below it on the stack. And this time, it is Stranger
that will make the call to
doPrivileged()
, not Friend
.
When the Example2d
program invokes doYourThing()
on the Friend
object referenced from the friend
variable, the
Friend
object invokes doYourThing()
on the
Stranger
object, which (because direct
is
false
) invokes doPrivileged()
, passing in the anonymous
inner class instance that implements PrivilegedAction
. The
doPrivileged()
method invokes run()
on the passed
PrivilegedAction
object, which invokes doYourThing()
on the TextFileDisplayer
object.
As in the previous two examples, TextFileDisplayer
's
doYourThing()
method attempts to open and read a file named
"answer.txt"
in the current directory and print its contents to the standard output.
When TextFileDisplayer
's doYourThing()
method
creates a new FileReader
object, the FileReader
constructor creates a new FileInputStream
, whose constructor checks to see
whether or not a security manager has been installed. As in all the examples, the concrete
SecurityManager
has been installed, so the
FileInputStream
's constructor invokes checkRead()
on the
concrete SecurityManager
. The checkRead()
method
instantiates a new FilePermission
object representing permission to read file
answer.txt
and passes that object to the concrete
SecurityManager
's checkPermission()
method, which
passes the object on to the checkPermission()
method of the
AccessController
. The AccessController
's
checkPermission()
method performs the stack inspection to determine whether
this thread should be allowed to open file answer.txt
for reading. The stack
presented to the AccessController
by Example2d
is shown
in Figure 3-9.
Example2d
: frame five doesn't have permission.
The call stack to be inspected in Example2d
looks similar to the call stack
inspected in Example2c
. The only difference is that Friend
and
Stranger
have swapped positions. As always, stack inspection starts at the top of the
stack and proceeds on down the stack towards frame one. But alas, once again the inspection process will
not actually reach frame one. When the AccessController
reaches frame five, it
discovers a stack frame associated with the STRANGER protection domain, which doesn't have permission
to read answer.txt
. As a result of this discovery, the
AccessController
throws an
AccessControlException
, indicating the requested read of
answer.txt
should not be performed.
Had the Stranger
class been able to enlist the assistance of an instance of some
class that implemented PrivilegedAction
, performed the desired invocation of the
TextFileDisplayer
's doYourThing()
method, and
belonged to a protection domain that has permission to read >answer.txt
,
Stranger
's attempt to open answer.txt
with the help of
doPrivileged()
would have still been futile. Imagine, for example, that the code of
the run()
method represented by frame five of Example2d
's call
stack had been associated with to the CD-ROM protection domain. In that case, the
AccessController
would have determined that frame five had permission to open
answer.txt
and continued on to frame four. At frame four, the
AccessController
would have discovered the
doPrivileged()
invocation. As a result of this discovery, the
AccessController
would make one more check: it would make certain the method
that invoked doPrivileged()
, which in this case was
Stranger
's doYourThing()
method represented by stack
frame three, has permission to read file answer.txt
. Because frame three is
associated with the STRANGER protection domain that doesn't have permission to read
answer.txt
, the AccessController
would still throw an
AccessControlException
.
To get the Example2d
application to work as intended, you must start the
application with yet another appropriate command. When using the java
program
from the Java 2 SDK version 1.2, the appropriate command takes the form:
java -Djava.security.manager -Djava.security.policy=policyfile.txt - Dcom.artima.ijvm.cdrom.home=d:\books\InsideJVM\manuscript\cdrom -cp .;jars/friend.jar;jars/stranger.jar Example2d
This command, which is contained in the ex2d.bat
file in the
security/ex2
directory of the CD-ROM, is an example of the kind of command
you'll need to use to get the example to work. As before, to execute Example2d
on
your own system, you must set the com.artima.ijvm.cdrom.home
property to
the security/ex2
directory of your CD-ROM, or to whatever directory you may
have copied the security/ex2
directory from the CD-ROM. When you run this
program, you should see the kind of output that crackers everywhere hate to see:
Exception in thread "main" java.security.AccessControlException: access denied (java.io.FilePermission answer.txt read) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:195) at java.security.AccessController.checkPermission(AccessController.java:403) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.SecurityManager.checkRead(SecurityManager.java:873) at java.io.FileInputStream.(FileInputStream.java:65) at java.io.FileReader. (FileReader.java:35) at TextFileDisplayer.doYourThing(TextFileDisplayer.java, Compiled Code) at com.artima.security.stranger.Stranger$1.run(Stranger.java:27) at java.security.AccessController.doPrivileged(Native Method) at com.artima.security.stranger.Stranger.doYourThing(Stranger.java:24) at com.artima.security.friend.Friend.doYourThing(Friend.java:21) at Example2d.main(Example2d.java:21)
Sponsored Links
|