On Mon, 12 Aug 2002, Per Kreipke wrote:

> Date: Mon, 12 Aug 2002 16:33:15 -0400
> From: Per Kreipke <[EMAIL PROTECTED]>
> Reply-To: Tomcat Users List <[EMAIL PROTECTED]>
> To: Tomcat Users List <[EMAIL PROTECTED]>
> Subject: RE: [Q] Realms, Principals, et al...
>
> Craig,
>
> Thanks for the very detailed reply.
>
> > > > > Q1:
> > > > > ===
> > > > >
> > > > > If GenericPrincipal isn't available from webapps, is there
> > > > another way to
> > > > > get at the complete list of roles for a given user and
> > their password?
> > > > >
> > > >
> > > > Not from a webapp through a portable API.  What you see
> > (isUserInRole())
> > > > is what you get.
> > > >
> > > > However, properly configured web.xml files will have <security-role>
> > > > elements for all of the role names that are referenced by
> > that webapp, so
> > > > you might try reading them (by parsing /WEB-INF/web.xml) and
> > trying all of
> > > > those names through isUserInRole().  Of course, that doesn't
> > help you if
> > > > the webapp doesn't define them all ...
> > >
> > > ... or if the set of all roles is dynamic, a shortfall of the
> > declarative
> > > servlet security API.
> > >
> >
> > If the roles are dynamic, how is it that anyone believes it is possible to
> > enumerate "the" set of roles for a given user?
>
> Ok, I didn't realize that servlet spec says that roles must be a fixed
> enumeration for the life of a web application.
>
> Maybe that's where I mis-understand how servlets are supposed to use roles
> in web applications. Probably because I've never found any design patterns
> for how to use servlet container security for different internet application
> scenarios, only code samples on what to call when.
>
> IMO (<- where the impedence mismatch probably is), the servlet API is
> purposely generic enough (user's key and roles are simply strings) that
> roles could be used in multitude of ways to enforce security, except that
> the API only allows one question: isUserInRole().
>

That's a pretty accurate understanding.  The challenge is that the range
of existing security technologies is gigantic and getting bigger.

Just as a simple example, consider the concept of "group" that many
security environments define.  Either of the following mappings would be
perfectly legal from the perspective of a servlet container (or a J2EE app
server):

* "Group == Role" (since Tomcat 3.x and 4.0 do not have any specific
  concept of a group, this is effectively what they implement).

* "Group == set of roles inherited by all members of the group" (supported
  explicitly by Tomcat 4.1).

The details of how role is mapped to real-world things is up to the
container.

> - they are often mentioned as being roughly equivalent to *nix groups: a
> collection of users
> - they could also be used as a collection of permissions, as in RBAC systems
> - can't one imagine having to manage permissions among companies,
> workgroups, projects, users?
>
> > > > > I need the complete list of roles for the current user and
> > password to
> > > > > implement a connector from Cocoon authentication to the container
> > > > > authentication.
> > > > >
> > > >
> > > > It's not at all clear to me that every possible Realm
> > implementation will
> > > > be able to articulate such a list -- or that the list won't
> > change over
> > > > time.  For example, it's perfectly feasible to implement a
> > Realm that says
> > > > "user Joe has this role, but only from 8am to 5pm on
> > weekdays".  It sounds
> > > > like the Cocoon folks might want to do a little more thinking
> > about their
> > > > design.
> > >
> > > I don't know that it's their mistake, I'm just talking about
> > wrapping the
> > > GenericPrincipal class.
> >
> > GenericPrincipal is an internal implementation detail for how the existing
> > Realms implement things.  It is not part of the public API that Tomcat
> > exposes to a webapp.  There is no guarantee that any other container
> > creates something like this that has the roles built in to the Principal
> > object itself.
>
> Ok, and I understand Tomcat's role as the default/sample Servlet container
> and why it needs to remain committed to the API as defined.
>
> Perhaps in the future, the following APIs will get an enhancement:
>
> java.lang.String getRemoteUser()
> boolean isUserInRole(String role)
> java.security.Principal getUserPrincipal()
>
> // NEW
> String[] getUserRoles() // roles are already strings
>

The problem is that this method is not implementable on all possible
security domains, for the definition of "role" provided by those domains.
Putting it into the API therefore seems very unlikely to ever get added.

>
> Perhaps getRoles() on GenericPrincipal shouldn't be public but adding the
> following to HttpServletRequest would allow servlet containers to implement
> them on either the Principal or elsewhere. Tomcat could even expose it now
> through the wrapper or facade.
>
> > > Isn't it true that you can't do that from _any_
> > > webapp, much less Cocoon. E.g. given any of the current Tomcat
> > Realms, how
> > > could you do your 'Joe' example?
> > >
> >
> > Implementing time-sensitive permissions would actually be pretty easy -
> > subclass the Realm implementation that talks to the right kind of
> > persistent store, and add logic in its hasRole() method to return "false"
>
> > outside the allowed times, even if the role is listed in the
> > GenericPrincipal instance.  Obviously, you'd want to add more information
> > to the database (or whatever) containing the user information, but that's
> > all internal implementation stuff.
>
> Ok. I'm guessing that the subclass you're mention will still be managed by
> the Catalina class loader otherwise it doesn't have access to the Realm it
> subclasses.
>
> What it won't allow me to do is define three roles today, one for each
> shift: morning, afternoon, and evening. Then add new ones to the database
> ('midnight', 'all-overnight', 'doctor-in-residence-40-hours'), in the
> business layer without adding them to the web layer also in the web.xml for
> the app.
>

This is not currently supported by J2EE deployment descriptors (although
Tomcat standalone does not enforce the rule) -- you are required by the
specs to enumerate all role names you want to reference.

> > If you're following what's going on with Tomcat 5 on the developer's list,
> > you'll see an extension being added to the Realm interface that passes the
> > current request in to the hasRole() method as well (so that it can make
> > decisions based on characteristics of the current request).  This is being
> > done in support of implementing JSR-115, which is an SPI between a
> > container (like Tomcat) and an authorization service that might implement
> > arbitrarily complex rules for deciding whether a user, for this request,
> > at this date and time, has a requested role.  But, from the web
> > application's point of view, nothing changes -- isUserInRole() is how you
> > can dynamically ask the question for a particular role.
>
> I'm showing my naivete: how can isUserInRole() be expressive enough to ask
> all the security questions one could think of? Is everyone writing
> authentication filters that need recompilation every time a application's
> site map changes? Or are people encoding
> company/client/workgroup/permissions in the role string?
>

Depending on how fine grained you want to define "role", I think so.  Note
that exactly the same functionality exists in EJBs in the isCallerInRole()
method -- and it has seemed sufficient to date.

Note that roles are also the basis for security constraints, and have been
since Servlet 2.2.

> > If you want to expose a Principal object (via getUserPrincipal()) that can
> > be cast by a webapp to get more data than just the name, that would be
> > feasible;
> >
> > * Create a new class implementing Principal (and putting it in
> >   common/lib or common/classes so that it's visible to both
> >   Tomcat and your app)
> >
> > * Build your own Realm implementation that creates and returns one of
> >   these Principals from the authenticate() method.
> >
> > Obviously (I hope), this would tie you directly to Tomcat 4 internals.
> > There's nothing portable in Servlet 2.3 (or 2.4) for enumerating roles --
> > in fact, if I remember right, JSR-115 dispensed with the idea of creating
> > API for enumerating all the roles owned by a user because it was not
> > going to be possible for many environments.
>
> I think that's the way I'll try next.
>
> > > P.s. I know you spend a huge amount of time helping people on
> > this and other
> > > lists, so I hesitate to ask again but...
> > >
> > > Is the implementation of JAASRealm in 4.1 backwards compatible to 4.0.4?
> > >
> >
> > Haven't got a clue.  In theory it should be, but I've never tried.
>
> Ah, sorry, thought you wrote that one too. My apologies, should have paid
> attention.
>

Well, I did write JAASRealm ... but I never tried it under 4.0.  I don't
see why it *shouldn't* work (the Realm interface didn't really change in
4.1), but I've only experimented with it under 4.1.

> Thanks again for your patience,
> Per
>

Craig


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to