In the discussion that follows, we make the distinction between trusted and untrusted classes. Generally, an implementation of a security manager allows more operations for trusted classes than for untrusted classes. Whether or not a class is trusted is a complex decision based upon many factors—not the least of which is the release of Java under which the program is running. The default notion of what constitutes a trusted class has changed significantly between releases of Java:
In Java 1.1, that same rule applies, but a class that is loaded from a JAR file may carry with it a digital signature that allows it to be given extra privileges.
In Java 1.2, a class that is loaded from the core API is considered
trusted and may perform any operation it wants to. Otherwise, classes
are (by default) given privileges based upon where they were loaded
from, including if they were loaded from the
CLASSPATH. However, this applies only when
certain command-line arguments are present; in the default method of
loading applications, items from the
are generally considered trusted.
Nothing inherent in the design of the security manager requires
security to be enforced as an all-or-nothing proposition for each
class. It’s possible to write a security manager that gives
access to certain parts of the filesystem only to certain classes
(even classes that came from the network), or to write a security
manager that prohibits classes loaded from the
CLASSPATH from performing operations that are
normally permitted to classes loaded from the filesystem. A security
manager can be as simple or as sophisticated as its author desires,
with the result that the security manager can enforce a simple binary
yes-or-no policy for operations, or it can enforce a very
specialized, very detailed policy. This is true of all security
managers in all versions of Java, though as we’ll see in Chapter 5, one of the prime benefits of Java 1.2 is that
it makes it much easier to achieve fine-grained security policies.
However, even though a sophisticated security manager can enforce a
very detailed security policy, most implementations of the security
manager (especially implementations that occur within popular
Java-enabled browsers) assume that a trusted class is one that has
been loaded from the
CLASSPATH, while an
untrusted class is one that has been loaded from a class loader.
Furthermore, trusted classes are normally permitted to perform any
operation, while an untrusted class is normally subjected to the full
extent of the provisions of the security manager.
This dichotomy is essentially the same as the one we normally make
between applications and applets: since an application is loaded
entirely through the
CLASSPATH, all of its
classes are considered trusted, and the application can perform any
operation that it wants to. On the other hand, the classes that
comprise an applet are generally loaded from the network; hence they
are considered untrusted and denied any operation that has the
potential to violate the browser’s security policy.
Beginning with Java 1.1, this distinction became less clear (and Java 1.2 made it even fuzzier): classes now have the ability to be signed, and classes that are signed can be treated as trusted or untrusted. We discuss the rationale behind that idea in Chapter 7 and we fully explore signed classes in the last part of this book; for now, we’ll just keep in mind that some classes are trusted and some are not.