On Fri, 2003-05-16 at 02:32, Paul Boddie wrote:
> Hello,
>
> Matt Feifarek [mailto:matt@...] wrote:
> >
> > Terrel Shumway wrote:
> >
> > >What we are dealing with is *authorization*
>
> [...]
>
> > >There is no shorcut. Any authorization problem reduces eventually to a
> > >boolean function of three elements.
> > >
> > > 1) the actor
> > > 2) the action
> > > 3) the recipient (acted upon)
> > >
> > >Whether that function is defined in code or in a table, it still has to
> > >exist.
>
> What is interesting is if you compare authorisation APIs, such as that found
> within the Java Servlet API, with more comprehensive "capability" systems
> such as JAAS. Initially it seems like the Servlet API is too limited -
> applications find out whether the current user has a particular role, and
> they just get told about it after the authentication has occurred - whereas
> JAAS provides lots of different levels of control over what each
> authenticated user can do, access to different components is controlled by
> the runtime environment, and there are various plug-in capabilities for
> authentication, reminiscent of PAM.
>
> However, I believe that for many applications, the JAAS approach is just too
> confusing: lots of configuration options that arguably aren't interesting in
> many applications, inflexible use of files to define permissions on code
> objects despite the potential advantages of declarative security (in my
> opinion, as implemented in the version I tried some time ago).
Yes, Java is dumb :) Configuration is also dumb. Dynamic declaration
kicks static configuration's butt ;)
I really don't think the permission model has to be built into the rest
of the system at all. It comes down to that triple (actor, action,
recipient), though I would emphasize that the actor can take many
different forms -- for instance, in a capabilities system, the actor
would be a list of capabilities, not a particular identity. And more
advanced objects should be able to change the actor, for instance giving
the actor more permissions (that have been delegated by another user),
or taking permissions away for select operations.
I'd imagine it looking like:
class Document:
def view(self):
if not actor.permitted('view', self):
raise Forbidden
actor could be any sort of system -- capabilities, role-based,
ACL-based, or entirely novel. The Document class might have to have
extra methods, for instance if permissions are granted to classes of
documents... but that's all inside actor for now (which makes me feel
"actor" isn't the right name).
But anyway, that obviously won't work, because "actor" has just appeared
by magic. You don't want it to be an argument everywhere (like
view(self, actor)). That will create very unstable interfaces, because
permission issues can pop up deep inside nested function calls, after
the actor is no longer being passed around. And restricted objects can
appear anywhere as an application is being developed. Dynamic scoping
would be cool here :)
Of course, global variables work for this sort of thing. You even do
the entire dynamic scoping bit (at least functionally), like:
def delegate(proxyActor, func, *args, **kw):
realActor = actor
actor = proxyActor
func(*args, **kw)
actor = realActor
But that doesn't work in a threaded environment. Maybe it's cheating to
do:
_actors = {}
def setActor(actor):
_actors[threading.currentThread().getName()] = actor
def getActor():
return _actors[threading.currentThread().getName()]
It means you have to be a little careful about multithreading, you have
to set up the permission environment separately for each thread. But
that actually doesn't seem so hard -- certainly in normal operation it
wouldn't be hard in Webware.
Anyway, that's my rambling on the topic. I'm not sure what exactly I
was responding to anymore...
Ian
|