|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 4
Along with its request to write the message, the client passes its execution context in the form of an AccessControlContext instance. It obtains this instance by calling the getContext() method.
The server thread obtains the request from its queue. Before attempting to write to the log, it first checks the permissions
associated with the protection domains of the client by invoking the doPriviledged() method on the AccessController class. This method accepts an instance of the AccessControlContext class in addition to a block of code containing the security-sensitive operation.
Figure 2 illustrates how this works.

Figure 2. Permission resolution using an AccessControlContext instance
The arrows illustrate the path followed by the AccessController class as it decides whether or not to permit the operation. Beginning at the point where the security-critical operation
is attempted, the AccessController class examines each protection domain for the required permission. When it reaches the point at which the doPriviledged() method was called, it stops checking the current execution context and instead continues checking the client's execution
context. In this way, it considers the client's permissions when deciding whether or not to permit a security-sensitive operation.
An instance of the GuardedObject class "guards" a wrapped instance of another class from code that lacks the correct permissions.
Figure 3 illustrates the relationship between the GuardedObjectinstance, the Guard instance, and the wrapped object.

Figure 3. The GuardedObject and Guard instances
The following code illustrates how to use a GuardedObject instance and an associated Guard instance in the context of Situation 2.
public
static
class Consumer
implements Runnable
{
private
Producer m_producer = null;
public
void
link(Producer producer)
{
if (m_producer != producer)
{
m_producer = producer;
m_producer.link(this);
}
}
public
void
run()
{
for (int i = 0; i < 10; i++)
{
Object object = m_producer.retrieveLocation().getObject();
}
}
}
public
static
class Producer
implements Runnable
{
private
Consumer m_consumer = null;
public
void
link(Consumer consumer)
{
if (m_consumer != consumer)
{
m_consumer = consumer;
m_consumer.link(this);
}
}
private
String m_stringLocation = null;
public
synchronized
GuardedObject
retrieveLocation()
{
String stringLocation = null;
try
{
while (m_stringLocation == null) wait();
stringLocation = m_stringLocation;
m_stringLocation = null;
notifyAll();
}
catch (InterruptedException interruprtedexception)
{
}
try
{
GuardedObject guardedobject = new GuardedObject
(
new FileInputStream(stringLocation),
new FilePermission(stringLocation, "read")
);
return guardedobject;
}
catch (IOException ioexception)
{
ioexception.printStackTrace();
}
return null;
}
private
synchronized
void
storeLocation(String stringLocation)
throws InterruptedException
{
while (m_stringLocation != null) wait();
m_stringLocation = stringLocation;
notifyAll();
}
public
void
run()
{
while (true)
{
try
{
storeLocation("/tmp/out.tmp");
}
catch (InterruptedException interruptedexception)
{
break;
}
}
}
}
}
The preceding code contains two threads identified as the producer and the consumer. In response to consumer requests, the producer thread creates a FileInputStream instance, wraps it in an instance of the GuardedObject class, and returns it to the consumer.
AccessControlConttext API documentation http://java.sun.com/j2se/1.3/docs/api/java/security/AccessControlContext.html
GuardedObject API documentationGuardedObject classAccessControlContext class