|
|
|
Sponsored Link •
|
|
Advertisement
|
The next few sections give several examples to illustrate the manner in which the
AccessController performs stack inspection. In the upcoming examples, code
signed by both friend and stranger will be trusted to some
extent, but friend code will be trusted more than stranger
code. In particular, code signed by both friend and stranger
will be given permission to read a file named question.txt, which contains a
question. But although code signed by friend will be given permission to read a file
named answer.txt, which contains the answer to the question asked in
question.txt, code signed by stranger will not. These
permissions granted to friend and stranger are those outlined
in the policyfile.txt file from the security/ex2
directory of the CD-ROM, which was described earlier in this chapter. Each of the upcoming examples will
take their policy from policyfile.txt.
The stack inspection examples all make use of classes that implement the Doer
interface:
// On CD-ROM in file
// security/ex2/com/artima/security/doer/Doer.java
package com.artima.security.doer;
public interface Doer {
void doYourThing();
}
To be a Doer, a class must provide an implementation for one method:
doYourThing(). Classes that implement Doer can do whatever
they feel like in their doYourThing() method. For example, here's a class that
implements Doer named TextFileDisplayer whose "thing"
is to display the contents of a text file:
// On CD-ROM in file security/ex2/TextFileDisplayer.java
import com.artima.security.doer.Doer;
import java.io.FileReader;
import java.io.CharArrayWriter;
import java.io.IOException;
public class TextFileDisplayer implements Doer {
private String fileName;
public TextFileDisplayer(String fileName) {
this.fileName = fileName;
}
public void doYourThing() {
try {
FileReader fr = new FileReader(fileName);
try {
CharArrayWriter caw = new CharArrayWriter();
int c;
while ((c = fr.read()) != -1) {
caw.write(c);
}
System.out.println(caw.toString());
}
catch (IOException e) {
}
finally {
try {
fr.close();
}
catch (IOException e) {
}
}
}
catch (IOException e) {
}
}
}
When you create a TextFileDisplayer object, you must pass a file path name
to its constructor. The TextFileDisplayer constructor stores the passed path
name in the filename instance variable. When you invoke
doYourThing() on the TextFileDisplayer object, it will
attempt to open and read the contents of the file and print them at the standard output.
Another example of a doYourThing() method comes from classes
Friend and Stranger, which appeared earlier in this chapter in
the code signing example and are shown again here to refresh your memory:
// On CD-ROM in file
// security/ex2/com/artima/security/friend/Friend.java
package com.artima.security.friend;
import com.artima.security.doer.Doer;
import java.security.AccessController;
import java.security.PrivilegedAction;
public class Friend implements Doer {
private Doer next;
private boolean direct;
public Friend(Doer next, boolean direct) {
this.next = next;
this.direct = direct;
}
public void doYourThing() {
if (direct) {
next.doYourThing();
}
else {
AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
next.doYourThing();
return null;
}
}
);
}
}
}
// On CD-ROM in file
// security/ex2/com/artima/security/stranger/Stranger.java
package com.artima.security.stranger;
import com.artima.security.doer.Doer;
import java.security.AccessController;
import java.security.PrivilegedAction;
public class Stranger implements Doer {
private Doer next;
private boolean direct;
public Stranger(Doer next, boolean direct) {
this.next = next;
this.direct = direct;
}
public void doYourThing() {
if (direct) {
next.doYourThing();
}
else {
AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
next.doYourThing();
return null;
}
}
);
}
}
}
Friend and Stranger have much in common. They have
identical instance variables, constructors, and doYourThing() methods. They differ
only in their package and simple names. When you create a new Friend or
Stranger object, you must pass to the constructor a boolean value and a reference to
another object whose class implements the Doer interface. The constructor stores the
passed Doer reference in the instance variable, next, and the
boolean value in the instance variable, direct. When
doYourThing() is invoked on either a Friend or
Stranger object, the method invokes doYourThing(), either
directly or indirectly, on the Doer reference contained in next. If
direct is true, Friend or
Stranger's doYourThing() just invokes
doYourThing() directly on next. Otherwise,
Friend or Stranger's doYourThing()
invokes doYourThing() on next indirectly, by way of a
doPrivileged() call.
|
Sponsored Links
|