Section 8.2. Use Checked Collections to Enforce Security


8.2. Use Checked Collections to Enforce Security

It is important to be aware that the guarantees offered by generic types apply only if there are no unchecked warnings. This means that generic types are useless for ensuring security in code written by others, since you have no way of knowing whether that code raised unchecked warnings when it was compiled.

Say we have a class that defines an order, with a subclass that defines an authenticated order:

 class Order { ... } class AuthenticatedOrder extends Order { ... } 

Interfaces specify suppliers and processors of orders. Here the supplier is required to provide only authenticated orders, while the processor handles all kinds of orders:

 interface OrderSupplier {   public void addOrders(List<AuthenticatedOrder> orders); } interface OrderProcessor {   public void processOrders(List<? extends Order> orders); } 

From the types involved, you might think that the following broker guarantees that only authenticated orders can pass from the supplier to the processor:

 class NaiveBroker {   public void connect(OrderSupplier supplier,                       OrderProcessor processor)   {     List<AuthenticatedOrder> orders =       new ArrayList<AuthenticatedOrder>();     supplier.addOrders(orders);     processor.processOrders(orders);   } } 

But a devious supplier may, in fact, supply unauthenticated orders:

 class DeviousSupplier implements OrderSupplier {   public void addOrders(List<AuthenticatedOrder> orders) {     List raw = orders;     Order order = new Order();  // not authenticated     raw.add(order);  // unchecked call   } } 

Compiling the devious supplier will issue an unchecked warning, but the broker has no way of knowing this.

Incompetence can cause just as many problems as deviousness. Any code that issues unchecked warnings when compiled could cause similar problems, perhaps simply because the author made a mistake. In particular, legacy code may raise such problems, as described in the previous section.

The correct solution is for the broker to pass a checked list to the supplier:

 class WaryBroker {   public void connect(OrderSupplier supplier,                       OrderProcessor processor)   {     List<AuthenticatedOrder> orders =         new ArrayList<AuthenticatedOrder>();     supplier.addOrders(         Collections.checkedList(orders, AuthenticatedOrder.class));     processor.processOrders(orders);   } } 

Now a class cast exception will be raised if the supplier attempts to add anything to the list that is not an authenticated order.

Checked collections are not the only technique for enforcing security. If the interface that supplies orders returns a list instead of accepting a list, then the broker can use the empty loop technique of the previous section to ensure that lists contain only authorized orders before passing them on. One can also use specialization, as described in the next section, to create a special type of list that can contain only authorized orders.




Java Generics and Collections
Java Generics and Collections
ISBN: 0596527756
EAN: 2147483647
Year: 2006
Pages: 136

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net