users@glassfish.java.net

EJB authorization - getting the permissions from application clients

From: Piero Filippin <filippinp_at_yahoo.co.uk>
Date: Thu, 25 Oct 2007 13:45:44 +0100

Hi,
I have a question about the EJB authorization, but I would like first to
explain what I am trying to do with an example, so you can spot any
possible flaw with my process.

Let say I have a warehouse management application using stateless
beans, accessed using a Java application client. I have many members of
the staff, each one will belong to a group, let say "*admin*" or "*user*".

Each group has multiple roles associated (let say "*listitems*" and
"*additem*"); I use the role to identify what set of actions a
particular group can do.

In my example:
*Admins *can *listItems *and *addItem*
*Users *can only *listItems*

The mapping is in an XML file, which is great because this allows me to
easily create new groups assigning them only a subset of the roles as
required (without modifying my code).
<sun-application>
    <security-role-mapping>
        <role-name>*listitems*</role-name>
        <role-name>*additem*</role-name>
        <group-name>*admin*</group-name>
    </security-role-mapping>

    <security-role-mapping>
        <role-name>*listitems*</role-name>
        <group-name>*user*</group-name>
    </security-role-mapping>
    <realm>MyRealm</realm>
</sun-application>

This is quite easy to do with JavaEE, I can annotate each method in my
bean with the required role, so "*users*" will be allowed to get
information about the Items but will get an exception if they try to
create a new one.

The bean code is something like:

@Stateless
class WarehouseImpl implements Warehouse {

    ...

    @RolesAllowed("*listItems*")
    public List<Item> getItemsInStock(){ ... }

    @RolesAllowed("*listItems*")
    public List<Item> getItemPrice(String itemName){ ... }

    @RolesAllowed("*addItem*")
    public void addItem(String itemName){ ... }

    @RolesAllowed("*addItem*")
    public void addItems(List<Item> items){ ... }

    ...

}

The problem I have is on the client side: I have a button for each
"action", each button triggers the corresponding method in the bean, and
I would like to display only the buttons corresponding to the allowed
actions, with the minimum effort possible.

Currently I have something like:

if (sessionContext.isCallerInRole("listItems")){// the user is
authorized to call getItemsInStock and getItemPrice
    JButton b1=new JButton("List Available Products");
    b1.addActionListener( ....... bean.getItemsInStock() ......);
    JButton b2=new JButton("List Available Products");
    b2.addActionListener( ....... bean.getItemPrice() ......);
}
if (sessionContext.isCallerInRole("additem")){
    ...
}

While this is working, it requires a lot of code duplication (the client
has to "embed" how methods are mapped to roles), and this can easily
lead to a mismatch between the real permissions and the interface
(anyway, without compromising the security)

I would like to be able to write something like:

"if my current user is allowed to call bean.getItemsInStock()" {
    JButton b=new JButton("List available products");
    b.addActionListener( ....... bean.getItemsInStock() ......);
}
"if my current user is allowed to call bean.getItemPrice()" {
    JButton b=new JButton("Get the pricing information");
    b.addActionListener( ....... bean.getItemPrice() ......);
}

So, my question is: what is the best way for an application client to
know if the current user is allowed to call a particular method in a bean?

Piero