directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Richard Wallace <rwall...@thewallacepack.net>
Subject Re: [authx] Help with complicated authorization
Date Sat, 18 Jun 2005 18:04:55 GMT
Vincent Tence wrote:

>On Fri, 2005-06-17 at 11:05 -0700, Richard Wallace wrote:
>  
>
>>Hello everybody,
>>
>>I'm working on pushing our web development from PHP to Java at work.  
>>For the moment I've pretty much decided on using JSF/Spring/Hibernate at 
>>our presentation/business logic/persistence layers, though I think 
>>they're separated well enough that changing out one part of it shouldn't 
>>impact any of the others (except in the glue code).
>>    
>>
>
>We've embarked on a very ambitious project at work with Tapestry +
>Spring and Hibernate 3. I've used JSF over the last year and so far my
>experience with Tapestry is much better. If you can, check it out.
>There's a great book written by HLS - Tapestry in Action - to get you
>going. I really like the way Tapestry preserves you're HTML, which makes
>it easy to collaborate with UI design teams. JSF was awful in that
>respect.
>
>  
>
I looked into Tapestry a while ago and it seemed overly complicated from 
the very outset.  I mean, it seemed to require a lot of work to get even 
a simple webapp up and running.  I'll do some more looking into Tapestry 
because there are some things about JSF I don't like.  For one thing, it 
seems like it will be impossible to add form elements in a dynamic 
fashion with DHTML and not doing form resubmits.

>>Anyways, I'm trying to figure out how to do authorization.  
>>Authentication is pretty simple I think, but the authorization is pretty 
>>complex.  Instead of a user having or not having permission to access a 
>>page (container webapp security) or having or not having permissions to 
>>run certain actions (JAAS), we need finer grained permissions based on 
>>objects and the users relationship to the object.
>>    
>>
>
>As Alex said, that's the kind of problem AuthX aims to solve.
>
><snip/>
>
>  
>
>>I'm wondering how I might implement this with AuthX.  Do I simply create 
>>custom permissions classes, like ProjectPermission and TaskPermission?  
>>Then, when implementing the implies() method what do I do?  Is that 
>>where I would do these checks to see if the user has the required 
>>ability to do the desired operation?
>>    
>>
>
>Correct. You need to create custom Permission classes. The implies()
>method is used for granting/denying a permission by comparing the
>requested permission with the granted one. There's an example of that in
>the authx example app - look for the PurchasePermission.
>
>Let me try to explain. Suppose you decide to grant the permission to
>access a task to anybody that has the permission to access the project
>owning the task. In this case, you could code your ProjectPermission so
>that it implies any permission to access a task of the same project:
>
>(pseudo code)
>ProjectPermission {
>
>   ProjectPermission(Project project) {...}
>
>   boolean implies(Permission other) {
>	// suppose other is a task permissiom
>	task = ((TaskPermission) other).getTask();
>	return project.owns(task); // only grant if task belongs to project
>   }
>}
>
>In XML you would grant your subject with the ProjectPermission, lets
>say:
>
><policy>
>    <grant>
>        <subjects>
>            <username>Rich</username>
>        </subjects>
>        <permissions>
>            <project>Rich's Project</project>
>        </permissions>
>    <grant>
></policy>
>  
>
Are these policies loaded statically at startup or loaded dynamically?  
What about pulling these policies from a database?

>At runtime, when someone tries to access a task, you build a task
>permission:
>
>    taskPermission = new TaskPermission(task)
>
>and check if access is authorized:
>
>    authorizer.renderDecision( subject, taskPermission )
>
>The rule engine will check if the subject is Rich and if it is the case,
>will see that Rich has the ProjectPermission and will check if this
>permission implies the TaskPermission. If the task belongs to Rich's
>Project, access will be granted.
>
>That's somewhat simplified, but I hope you get the idea.
>
>  
>
I do.  One thing I like about Acegi is the use of interceptors so you 
can write all your Spring services and then just wire in the 
authorization stuff without having to modify the code.

>>think I'm a little lost because of all the groovy stuff.  Does anyone 
>>have an example app that I can work from that doesn't have groovy?
>>    
>>
>
>AuthX introduces a rule based system to implement authorization. Rules
>are much more flexible than what you can do with an RBAC system. In fact
>a rule is anything that implements the Rule interface (no surprise
>here):
>
>Rule {
>    void evaluate(AuthorizationRequest request);
>}
>
>It's very easy to implement RBAC using AuthX rule mechanism. It's a
>matter of defining a set of rules that authorize access to a resource if
>a subject has a given principal - in this case, a specific
>RolePrincipal. But you can do much more with rules. 
>
>The way you define your rules is pluggable in AuthX, and 2 mechanisms
>are provided out-of-the box.
>
>1. The first one is to use an XML document. The XMLRuleSetBuilder
>provided by AuthX will be parse and interpret your XML document, which
>means it neds to know how to deal with the XML elements. A set of XML
>elements are understood out of the box, such as:
>
><grant>, <deny>, <any>, <none>, <username>, <role>,
<group>, <and>,
><or>, ... and you mix them to express your authorization logic.
>
>Furthermore, you can plug your own element interpreters to
>XMLRuleSetBuilder. This is useful to represent your permissions, which
>are typically application dependent. In your case, you would introduce 2
>builders to define elements like <project> and <task> that represent
>your project and task permission.
>
>XML is fine, but it lacks the power of expressing more complicated needs
>and for every XML element you introduce, there need to be an interpreter
>that undertansa it's meaning. That is somewhat limitating and AuthX
>wants to support of wide range of authorization systems.
>
>This is where the scripted rules comes into play. 
>
>2. Using groovy (in the future, we could support other scripting
>languages, such as rhino, beanshell, pnuts, ...) to define rules is much
>more powerful. Just implement the rule interface and code what you need.
>I believe this is the best way to allow any kind of logic to be plugged
>into the authorization subsystem.
>
>For example, if we want to grant any permissions to canadian people, we
>would write it like this in XML:
>
><policy>
>    <grant>
>        <subjects>
>            <group>canadians</group>
>        </subjects>
>        <permissions>
>            <any/>
>        </permissions>
>    <grant>
></policy>
>
>And like this in groovy:
>
>class GrantCanadiansAnythingRule {
>
>    evaluate( request ) {
>        canadians = new GroupPrincipal("canadians")
>        if (request.getSubject().getPrincipals().contains(canadians))
>            request.grant()
>    }
>}
>
>Using a scripted language is much more powerful than using XML.
>Furthermore, you could well define your own domain specific language,
>write the script interpreter for it and let your security officers write
>their security rules themselves. Ok maybe you would just dream of doing
>it ;-)
>
>If we come back to our project example above, you could well use a
>groovy rule to give access to any project manager to his own projects
>tasks:
>
>// pesudo code
>class GrantProjectManagerAccessToTheirProjects {
>
>    GrantProjectManagerAccessToTheirProjects( ProjectManagerRepository
>repository )
>
>    evaluate( request ) {
>        subject = request.getSubject()
>        projectManagers = new GroupPrincipal("Project Managers")
>
>        // This rule only applies to pm
>        if (!subject.getPrincipals().contains(projectManagers)) return 
>
>        // This rule only applies to task permissions
>        if (!(request.getPermission() instance of TaskPermission))
>return
>
>        // Ok so this guy is a project manager, get it from the repo
>        Set usernames = subject.getPrincipals(UsernamePrincipal.class);
>        // in general, there will be one username in the set
>        manager = repository.getProjectManager(username)
>
>        // iterate over the list of projects of the manager to see if
>the task
>        // is in one of them
>        task = request.getPermission().getTask()
>
>        projects = manager.ownedProjects()
>        for ( each p in projects ) {
>                if (p.owns(task)) {
>                    request.grant()
>                    return
>                 }
>        }
>        request.deny()
>    }
>}
>
>What's interesting to note here, is that you can use Dependency
>Injection with your rules - currently AuthX support CI using
>PicoContainer, but support for other containers is possible. In the
>example, your DI container would provide the ProjectManager repository.
>
>I hope it helps understand the reasoning for having scripted rules. You
>can have a look to the example application in the source tree. It's a
>simple web app that demonstrates the concepts of AuthX, using both XML
>rules and groovy rules.
>
>If anything else, I'll be happy to answer any question you might have.
>We have a very important project at work that has started over 2 months
>ago and I'm in charge. It has drained almost most of my freetime and I
>don't see it changing before the end of the summer. I'm sorry I've not
>been available at all for a long time. Nevertheless, I have resumed
>working on AuthX recently. What are the things you would like to see
>implemented? That'll help prioritize the backlog. I was thinking of
>working on the Hibernate authenticator using Hibernate next. WDYT?
>  
>
It all sounds very cool.  Unfortunately, I need to start cranking some 
stuff out right away, so I think I'll need to go with Acegi for now.  As 
for where to start, it's hard to say since I'm not familiar enough with 
what's there.  I would say probably getting the policy stuff to be more 
dynamic (if it isn't already) would be the first thing to work on.

Thanks for the suggestions,
Rich

Mime
View raw message