Announcement Announcement Module
Collapse
No announcement yet.
authorisation more complex than isUserInRole Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • authorisation more complex than isUserInRole

    in my application the users authority to perform a particular buisness-logic depends not only on isUserInRole. it is quite more complex.
    e.g. depends the users authority to edit or delete a category-object on the user being the author of the category. or the user may have category-specific privileges: a user may own the privileges to edit or delete category A but is not authorized to edit or delete category b.

    (so the database containing the tables representing the user-domain-objects can be compared with the system database of a mysqldatabaseserver:
    the users have database-specific rights: there is a user table and a table for the databases and a join table which contains the privileges.)

    so there has to be extra buisness logic to determine if a user is authorized to perform a particular buisness-logic:

    my domain model:


    Code:
    public class User {
    	private String id;
    
    	//key-object is a Category object, value object is a CategoryPrivileges object 
    	private Map categoryPrivileges = new HashMap();
    
    	public Map getCategoryPrivileges() {
    		return categoryPrivileges;
    	}
    }
    
    
    public class Category {
    	private String name;
    	private User author;
    
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public User getAuthor() {
    		return author;
    	}
    	public void setAuthor(User author) {
    		this.author = author;
    	}
    	
    	
    
    }
    
    public class CategoryPrivileges {
    	private boolean privEdit = false;
    	private boolean privDelete = false;
    	public boolean getPrivEdit() {
    		return privEdit;
    	}	
    
    	
    }

    the buisness-class

    Code:
    public class Application {
    	public static final int EDIT_CATEGORY = 1;
    
    	
    	private CategoryDao categoryDao;
    
    
    	public Category findCategoryById(long id) {
    		return this.categoryDao.findById(id);
    	}
    	
    	public void editCategory(Category category, User performer) throws UnauthorizedException {
    		if (this.canPerform(performer, this.EDIT_CATEGORY, category))
    			throw new UnauthorizedException("not authorized");
    		this.categoryDao.save(category);
    	}
    
    	public static boolean canPerform(User performer, int action, Object object) {
    		switch (action) {
    		case EDIT_CATEGORY: {
    			Category category = (Category) object;
    			//the user has the authority to perform the buisnesslogic if he 
    			//either is the author or he owns the required privs for this category
    			return (performer.getCategoryPrivileges().containsKey(category)
    			&& ((CategoryPrivileges) performer.getCategoryPrivileges().get(category)).getPrivEdit())
    			
    			|| performer.equals(category.getAuthor());
    		}
    
    
    		default:
    			throw new RuntimeException("Invalid action.");
    		}
    	}	
    }
    so is the acegi-framwork suitalbe for that, if yes: does acegi also work with jdo? if not how would a good object-design for such a security framework look like. can you please give me some tips.

    thx

  • #2
    Hi derKaiser,

    There are many ways to achieve your goals with ACEGI, i think.

    The ability of a user to edit or delete a category can typicallly be modelized through an ACL.

    A user can be granted a permission (e.g. edit, delete) for a domain object (e.g. a category) by an AclEntryVoter. This voter will rely on an AclManager, then AclProvider that will be able to provide it with a list of granted users for a permission on a specific domain object.

    AclEntry, AclVoter are part of the ACEGI library. The reference documentation gives a good idea of how to use this.

    Modeling the fact that a the user is the author of the category can be achieved through calculation at Authentication population time. I am currently encountering the problem: I have to grant the user for access to a feature 1 only if his/her enterprise has a subscription for a particular feature 2. To solve this, I chose to consider this access as a new Granted Authority. While populating the newly authenticated user, I retrieve his/her enterprise's subscriptions, and if it has a subscription for feature2, I add "SUBSCRIBER_FEATURE2" authority to this user's details.

    So, to answer your question: Yes ACEGI can suit your need with custom role definition and use of ACLs.

    Concering your domain objects, I think you can define your CategoryPrivileges class with a private int mask field, rather than a finite number of fields representing you privileges. this will be extensible easier.

    You could consider the categoryPrivileges field of your User Class as a standalone class, eg.:

    Code:
    public class UserCategoryPrivilege
    {
        private User user;
        private CategoryPrivileges categoryPrivileges; // Containing the permission mask
        private Category category; // The protected domain object
    }

    And to use it with ACLS:

    Code:
    public UserCategoryPrivilegeAclEntryWrapper implements AclEntry
    {
       private UserCategoryPrivilege userCategoryPrivilege;
    
       // ACLEntry methods
    }
    And I think it is not a good idea to provide your Category class with the author field. Actually, from a functionnal point of view, a category should not know about the user that created it.

    Hoping this will be helpful,

    Comment


    • #3
      ok nice

      i'm going to study the documentaion now. but one last question:
      i've read the framework uses its own dao's. so is there a possibility to use jdo with acegi.

      thx

      Comment


      • #4
        dao =jdo

        Hi derKaiser,

        Yes you can use whatever implementation of net.sf.acegisecurity.providers.dao.AuthenticationD ao and wire it in the DaoAuthenticationProvider.

        We actually use Hibernate as underlaying implementation.

        Hope it helps

        paskos

        Comment

        Working...
        X