The Artima Developer Community
Sponsored Link

Java Buzz Forum
Method-Invocation Level ACL Style Security via Interception

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Brian McCallister

Posts: 1282
Nickname: frums
Registered: Sep, 2003

Brian McCallister is JustaProgrammer who thinks too much.
Method-Invocation Level ACL Style Security via Interception Posted: Dec 22, 2003 7:17 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Brian McCallister.
Original Post: Method-Invocation Level ACL Style Security via Interception
Feed Title: Waste of Time
Feed URL: http://kasparov.skife.org/blog/index.rss
Feed Description: A simple waste of time and weblog experiment
Latest Java Buzz Posts
Latest Java Buzz Posts by Brian McCallister
Latest Posts From Waste of Time

Advertisement

Checked in (and pushed a snapshot) of the interception library which Chris Nokleberg and I are working on. I started to put together an iptables style method invocation filter based upon actor-rule filtering. Using just interception, as compared to full AOP via AspectJ or whatnot doesn't allow access to the calling context, so we have to cheat a little bit and require registering the actor with the rule broker -- but it is done as a ThreadLocal so as to be easily used in a servlet or other J2EE environment.

Right now there are two levels of filtering through the security filter and broker. The first is a very course grained filtering, which is also much more efficient, based solely on static invocation information -- this is what you have the SecurityInterceptor match on:


InterceptionBroker broker = new InterceptionBroker();
SecurityInterceptor intercept = new SecurityInterceptor();
broker.addInterceptor(intercept, new NamedSignature("execute"));

The code above tells the interception broker that we we want to intercept and run through the security tests on any method named "execute" -- sudh as would be used on a typical Command style web application. If the method signature doesn't match the test (method name is "execute") than it isn't intrercepted and is allowed to continue.

The next level of filtering is done at invocation time, so is slower. To use this we need to register a SecurityBroker with the SecurityInterceptor


SecurityBroker sec = new SecurityBroker();
intercept.setSecurityBroker(sec);

sec.appendRule(new Rule()
{
    public boolean allow(InvocationContext ctx)
    {
        User user = (User)ctx.getActor();
        if (!user.isAuthenticated()) return false;
        else return true;    
    }
});

This sets a rule that makes sure the actor is authenticated.

All of this is fun, but until we see it used it isn't all that useful, so here is an example of using it. This is a quick-and-dirty Struts Action which delegates to a more flexible Command


package org.skife.kim.struts.tools;

import org.skife.intercept.interceptors.security.Actor;
import org.skife.intercept.interceptors.security.SecurityBroker;
import org.skife.intercept.interceptors.security.AccessError;
import org.skife.intercept.interceptors.security.Rules;
import org.skife.intercept.interceptors.security.Rule;
import org.skife.intercept.interceptors.security.InvocationContext;
import org.skife.kim.model.User;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMessage;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DelegatingAction extends Action
{
    private static final CommandFactory factory;
    private static final SecurityBroker broker;
    static
    {
        bro
1000
ker = new SecurityBroker();
        broker.appendRule(new Rule()
        {
            public boolean allow(InvocationContext ctx)
            {
                User user = (User) ctx.getActor();
                if (user.getFirstName().equalsIgnoreCase("George"))
                {
                    return false;
                }
                return true;
            }
        });
        broker.appendRule(Rules.ALLOW);
        factory = new CommandFactory(broker);
    }

    public ActionForward execute(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) throws Exception
    {
        String cname = mapping.getParameter();
        Actor actor = (Actor) request.getSession().getAttribute("current-actor");
        broker.setActor(actor);
        Command comm = factory.build(cname);
        BeanUtils.copyProperties(comm, form);
        try
        {
            return mapping.findForward(comm.execute());
        }
        catch (AccessError e)
        {
            ActionErrors errors = new ActionErrors();
            errors.add("general", new ActionMessage(e.getMessage()));
            this.saveErrors(request, errors);
            return mapping.findForward("SecurityError");
        }
    }
}

The CommandFactory does the fun work:


package org.skife.kim.struts.tools;

import org.skife.intercept.InterceptionBroker;
import org.skife.intercept.signatures.NamedSignature;
import org.skife.intercept.interceptors.security.SecurityInterceptor;
import org.skife.intercept.interceptors.security.SecurityBroker;

import java.io.IOException;
import java.util.Properties;

public class CommandFactory
{
    private Properties registry;
    private InterceptionBroker broker;

    public CommandFactory(SecurityBroker sec)
    {
        broker = new InterceptionBroker();
        broker.addInterceptor(new SecurityInterceptor(sec), 
                              new NamedSignature("execute"));
        registry = new Properties();
        try
        {
            registry.load(CommandFactory.class.getClassLoader()
                    .getResourceAsStream("commands.properties"));
        }
        catch (IOException e)
        {
            throw new RuntimeException("Unable to load commands.properties", e);
        }
    }

    public Command build(String name)
    {
        String cname = registry.getProperty(name);
        try
        {
            return (Command)broker.wrap(Class.forName(cname).newInstance());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Error building Command: " + name, e);
        }
    }
}

The security broker is configured in a static initialization block in this action. In a real application it would be done in a seperate policy configurator, but this is just top demonstrate. FYI, the rules established in this broker block "George" from doing anything, but allow anyone else to execute any command they want to. Not realistic, but then this is just a sample application ;-)

Right now there isn't much in the way of sophisticated security rule handling. There is a single chain that is executed for everyone. It will be easy to chaneg this to support iptables style chains and jumping, or real rules systems, or delegating back to JAAS.

Right now I am wanting to rethink some of the filtering. I would like to make the static rule elements filter via the InterceptionBroker as that is much faster than executing the whole chain (until failure anyway) every time. I also need to add short-circuting for allowing progression as well as denying. The boolean return probably won't last as it really needs a PAM styl 1000 e "sufficient" to short circuit for authenticated admins etc.

Read: Method-Invocation Level ACL Style Security via Interception

Topic: Your Early Morning Coffee: CNN on Social Software, Java Jokes, BEA Previous Topic   Next Topic Topic: Sun Drops Bid to Join Eclipse

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use