Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

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

Secure thread collaboration across protection domains

Build solid applications with the AccessControlContext and the GuardedObject classes

  • Print
  • Feedback

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.

Class GuardedObject

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.

  • Print
  • Feedback

Resources