Writing a Security Manager
To write your own security manager, you must create a subclass
of the SecurityManager class. Your SecurityManager subclass
overrides various methods from SecurityManager to customize
the verifications and approvals needed in your Java application.
This page walks through an example security manager
that restricts reading and writing to the file system.
To get approval from the security manager, a method that opens
a file for reading invokes one of SecurityManager's checkRead()
methods. Similarly, a method that opens a file for writing invokes
one of SecurityManager's checkWrite() methods. If the security
manager approves the operation then the checkXXX() method
returns, otherwise checkXXX() throws a SecurityException.
To impose a stricter policy on file system accesses, our example SecurityManager
subclass must override SecurityManager's checkRead() and
checkWrite() methods. SecurityManager provides three versions
of checkRead() and two versions of checkWrite(). Each of
which should verify whether the application is allowed to open
a file for I/O. A policy frequently implemented by browsers is that applets
loaded over the network cannot read from or write to the local file system
unless the user approves it.
The policy implemented by our example prompts the user for a password when
the application attempts to open a file for reading or for writing.
If the password is correct then the access is allowed.
All security managers must be a subclass of SecurityManager. Thus, our
PasswordSecurityManager class extends
SecurityManager.
class PasswordSecurityManager extends SecurityManager {
. . .
}
Next, PasswordSecurityManager declares a private instance variable password
to contain the password that the user must enter in order to allow
the restricted file system accesses. The password is set upon construction:
PasswordSecurityManager(String password) {
super();
this.password = password;
}
The next method in the PasswordSecurityManager class is a private helper
method named accessOK(). This method prompts the user
for a password and verifies it. If the user enters a valid
password, the method returns true; otherwise, it returns false.
private boolean accessOK() {
int c;
DataInputStream dis = new DataInputStream(System.in);
String response;
System.out.println("What's the secret password?");
try {
response = dis.readLine();
if (response.equals(password))
return true;
else
return false;
} catch (IOException e) {
return false;
}
}
Finally at the end of the PasswordSecurityManager class are the three
overridden checkRead() methods and the two overridden
checkWrite() methods:
public void checkRead(FileDescriptor filedescriptor) {
if (!accessOK())
throw new SecurityException("Not a Chance!");
}
public void checkRead(String filename) {
if (!accessOK())
throw new SecurityException("No Way!");
}
public void checkRead(String filename, Object executionContext) {
if (!accessOK())
throw new SecurityException("Forget It!");
}
public void checkWrite(FileDescriptor filedescriptor) {
if (!accessOK())
throw new SecurityException("Not!");
}
public void checkWrite(String filename) {
if (!accessOK())
throw new SecurityException("Not Even!");
}
All the checkXXX() methods call accessOK()
to prompt the user for a password. If access is not OK,
then checkXXX() throws a SecurityException. Otherwise,
checkXXX() returns normally. Note that SecurityException
is a runtime exception, and as such does not need to be declared in
the throws clause of these methods.
checkRead() and checkWrite() are just a few of the
many of SecurityManager's
checkXXX() methods that verify various kinds of operations.
You can override or add any number of checkXXX() methods to
implement your security policy. You do not need to override all of
SecurityManager's checkXXX() methods, just the ones
that you want to customize. However, the default implementation provided
by the SecurityManager class for all checkXXX()
methods throws a SecurityException. In other words, by default the
SecurityManager class disallows all operations that are subject to
security restrictions. So you may find that you have to override
many of SecurityManager's checkXXX() methods
to get the behavior you want.
All of SecurityManager's checkXXX() methods operate in the
same way:
-
If access is allowed, the method returns.
-
If access is not allowed, the method throws a SecurityException.
Make sure that you implement your overridden checkXXX()
methods in this manner.
Well, that's it for our SecurityManager subclass. As you can see
implementing a SecurityManager is simple. You just:
-
Create a SecurityManager subclass.
-
Override a few methods.
The tricky part is determining which methods to override and implementing
your security policy.
Deciding What SecurityManager Methods to Override
will help you figure out which methods you should override depending
on what types of operations you'd like to protect.
The next page shows you how to install the
PasswordSecurityManager class as the on-duty security manager for your Java
application.
|