Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Java EE security model support ACL?

I used Java EE 6 with Glassfish v3.0.1, and I wonder if Java EE security model support ACL, and if so how fine-grained is it get?

EDITED
I implement Security using jdbc realm via glassfish v3, that the realm at runtime look into table USER inside the database to check for authentication, by looking at the password field and authorization by looking at the role field. The roles field only contain 2 either ADMINISTRATOR or DESIGNER. So it is a One-to-one map between user and role. At the managed bean level, I implemented this

private Principal getLoggedInUser()
{
    HttpServletRequest request =
            (HttpServletRequest) FacesContext.getCurrentInstance().
                getExternalContext().getRequest();
    if(request.isUserInRole("ADMINISTRATORS")){
        admin = true;
    }else{
        admin = false;
    }
    return request.getUserPrincipal();
}

public boolean isUserNotLogin()
{
    Principal loginUser = getLoggedInUser();
    if (loginUser == null)
    {
        return true;
    }
    return false;
}

public String getLoginUserName()
{
    Principal loginUser = getLoggedInUser();
    if (loginUser != null)
    {
        return loginUser.getName();
    }
    return "None";
} 

by calling isUserInRole, I can determine if the user is admin or not, then the JSF will render the content appropriately. However, that is not fine-grained enough (real quick background info: There are multiple projects, a project contains multiple drawings). Because if u are a DESIGNER, you can see all the drawings from all the projects (what if I only want tom to work on project A, while peter will work on project B, Cindy can supervised over the two project A and B). I want that, at runtime, when I create the user, I can specifically set what project can he/she see. Is there a way to accomplish this? NOTE: There are more than just two projects, the above example is just for demonstration.

like image 268
Thang Pham Avatar asked Aug 30 '10 22:08

Thang Pham


1 Answers

The Java EE security model authenticates a 'Principal' which may one have or more 'Roles'.

In the other dimension you have services and resources which need configurable 'Permissions' or 'Capabilities'.

In the configuration you determine which 'Principals' or 'Roles' have which 'Permissions' or 'Capabilities'.

In other words, yes it supports ACL and it is as fine grained as you want it to be, but you'll have to get used to the terminology.

In the answer of Vineet is the excellent suggestion to create 'roles' per project id. Since people must be assigned to projects anyhow, it is straightforward to to add the people to these groups at that time. Alternatively a timed script can update the group memberships based on the roles. The latter approach can be preferable, because it is easier to verify security if these decisions are in one place instead of scattered all over the administration code.

Alternatively you can use "coarse-grained" roles e.g. designer and make use of the database (or program logic) to restrict the views for the user logged in

SELECT p.* FROM projects p, assignments a WHERE p.id = a.projectId AND a.finishdate < NOW();

or

@Stateless class SomeThing {

    @Resource SessionContext ctx;

    @RolesAllowed("DESIGNER")
    public void doSomething(Project project) {
        String userName = ctx.getCallerPrincipal.getName();

        if (project.getTeamMembers().contains(userName) {
            // do stuff
        }
    }

}

Note that the coarse grained access control has here been done with an annotation instead of code. This can move a lot of hard to test boilerplate out of the code and save a lot of time.

There are similar features to render webpages where you can render parts of the screen based on the current user using a tag typically.

Also because security is such a wide reaching concern, I think it is better to use the provided features to get at the context than to pass a battery of boolean flags like isAdmin around as this quickly becomes very messy. It increases coupling and it is another thing making the classes harder to unit-test.

In many JSF implementations there are tags which can help rendering optional things. Here is are examples for richfaces and seam:

<!-- richfaces -->
<rich:panel header="Admin panel" rendered="#{rich:isUserInRole('admin')}">
  Very sensitive information
</rich:panel>

<!-- seam -->
<h:commandButton value="edit" rendered="#{isUserInRole['admin']}"/>.

Here is an article explaining how to add it to ADF

like image 64
Peter Tillemans Avatar answered Oct 10 '22 05:10

Peter Tillemans