Return-Path: Delivered-To: apmail-geronimo-user-archive@www.apache.org Received: (qmail 49590 invoked from network); 17 Nov 2009 09:01:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 17 Nov 2009 09:01:55 -0000 Received: (qmail 36756 invoked by uid 500); 17 Nov 2009 09:01:54 -0000 Delivered-To: apmail-geronimo-user-archive@geronimo.apache.org Received: (qmail 36707 invoked by uid 500); 17 Nov 2009 09:01:53 -0000 Mailing-List: contact user-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: user@geronimo.apache.org List-Id: Delivered-To: mailing list user@geronimo.apache.org Received: (qmail 36699 invoked by uid 99); 17 Nov 2009 09:01:53 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Nov 2009 09:01:53 +0000 X-ASF-Spam-Status: No, hits=1.2 required=10.0 tests=SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (nike.apache.org: local policy) Received: from [209.85.211.172] (HELO mail-yw0-f172.google.com) (209.85.211.172) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Nov 2009 09:01:45 +0000 Received: by ywh2 with SMTP id 2so6077970ywh.27 for ; Tue, 17 Nov 2009 01:01:23 -0800 (PST) MIME-Version: 1.0 Received: by 10.101.72.16 with SMTP id z16mr1778919ank.90.1258448483142; Tue, 17 Nov 2009 01:01:23 -0800 (PST) In-Reply-To: <1f3854d50911170025k224f816fo1ff2d1baa988b214@mail.gmail.com> References: <1f3854d50911160841p5a51994n6c64f223fb984b4c@mail.gmail.com> <56337A83-DA8F-4E38-9535-A037270DBD88@yahoo.com> <1f3854d50911161004r32b6b911v617156c18160c67c@mail.gmail.com> <1f3854d50911161039m2b71cf20te886f0412faead45@mail.gmail.com> <1200D4A9-4FEA-49A1-B53F-DE354BE6E48C@yahoo.com> <1f3854d50911170025k224f816fo1ff2d1baa988b214@mail.gmail.com> From: Quintin Beukes Date: Tue, 17 Nov 2009 11:01:03 +0200 Message-ID: <1f3854d50911170101l7ea21dcdu352ef38b52938993@mail.gmail.com> Subject: Re: Serious Problem with Roles To: user@geronimo.apache.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Virus-Checked: Checked by ClamAV on apache.org I think what I'm going to do is add another level of abstraction around roles in my database. Where I now have Operators->Roles I will have Operators->Roles->ContainerRoles So each module defines it's roles and has a OneToMany on ContainerRoles. ContainerRoles will then have a OneToOne mapping to a role in the deployment descriptor and my SQLLoginModule will then do another LEFT JOIN on ContainerRoles which would then become the GeronimoGroupPrincipals for the subject. Quintin Beukes On Tue, Nov 17, 2009 at 10:25 AM, Quintin Beukes wr= ote: > This is my situation. > > I have the server, which has the roles/users and EJB security with > @RolesAllowed. This is container managed and the important part, as > it's absolutely crucial that you can't execute what you're not allowed > to. This works fine. > > Further it's a modular system. You load the modules you want and they > work together to form a system. Each module has it's own roles. > > For example, we have the platform (core) module which defines > "Standard User" and "Admin". The "Admin" has access to almost > everything as each module lists it explicitly to be allowed to do > almost everything (just a few things like those for services which it > can't do). Then the personnel module which defines "Personnel Admin" > and "Personnel User". And for arguments sake on more called "Lamp" > with say, "Lamp Room" and some others. So Personnel module has no > concept of "Lamp Room". In the Lamp EJB when I do the mappings I here > list that the "Lamp Room" group maps to "Lamp Room", "Personnel User" > and "Standard User". So each module down the hierarchy lists the roles > upwards which it maps to, like in this case "Lamp Room" users need > read access to personnel as well. > > This is all fine for the server, as it works. The problem is on the > client. I need a way for this information to be retrieved from the > server. I am hoping to get the information as the server understands > it to reduce maintenance and thus avoid potential bugs. If I have to > start maintaining multiple hard coded lists of permissions I'm just > looking for trouble. Especially when another developer has to start > working on this code base, which is the case as I usually don't do the > maintenance. > > The reason I need it client side is to construct the UI. The main > terminal GUI is a desktop application and it has to > enable/disable/hide/show actions based on the user's roles. Also, > since it's modular I have exposed certain services, like for > navigation. Each module broadcasts only it's actions, and the > navigation module automatically takes care of authorization using > annotations on the action's class. The typical modular system... > trying to modularize everything and on duplication. > > Is there perhaps a way I can tell the server how to do the role > mappings programmatically? So, instead of listing it in a deployment > descriptor it's listed in the database and when one of my Singleton > beans load I can configure the role mappings? > > Quintin Beukes > > > > On Mon, Nov 16, 2009 at 10:37 PM, David Jencks w= rote: >> >> On Nov 16, 2009, at 10:39 AM, Quintin Beukes wrote: >> >>> Even if it means quite a bit of code. I seriously need a way to >>> determine the roles. It's either this or a massive overhaul on our >>> user/group/role system where the whole system is already >>> standing at 80000 lines of code. Changing the auth structure at this >>> point would postpone the release too much. >>> >>> This is the last thing standing between me and a phase 1 release. Any >>> suggestions would thus be greatly appreciated. >> >> I've also wanted a >> >> Collection getUserRoles() >> >> =C2=A0method but there isn't one. About the only thing you can do is >> >> List allRoles =3D //hard-code or read from a property file??? >> List userRoles =3D new ArrayList(); >> for (String role: allRoles) { >> =C2=A0if (context.isUserInRole(role)) { >> =C2=A0 =C2=A0userRoles.add(role); >> =C2=A0} >> } >> >> I'm curious why you need this much information for this kind of partiall= y >> app managed security. =C2=A0Maybe there's another way to approach this. >> >> One possibility is to add more container managed security -- a whole >> additional kind of permission -- to your setup. =C2=A0You can write secu= rity >> deployers to add more role-permission mappings to the security system an= d >> then at runtime your app can test with accessControlContext.implies(new >> MySpecialPermission(info)). =C2=A0This may well not be enough info, but = if this >> sounds remotely plausible let me know.... >> >> hope this helps >> david jencks >> >> >> >>> >>> Quintin Beukes >>> >>> >>> >>> On Mon, Nov 16, 2009 at 8:04 PM, Quintin Beukes >>> wrote: >>>> >>>> Oh yes :< >>>> >>>> I was so focussed on my initial problem that I forgot about the >>>> workings of isCallerInRole(). You have to do @DeclareRoles({..}) at >>>> the class level. I actually do this everywhere I call >>>> isCallerInRole(). It was just in this case where I'm trying to >>>> determine the call's roles. The subject wasn't working (I now know >>>> it's obvious, as a role isn't a principal), so I tried to do >>>> isCallerInRole() without using it properly. >>>> >>>> I have a big problem though. >>>> >>>> Is there any way at all to get a list of roles for a user as mapped in >>>> the deployment descriptor? Even if I have to query the Geronimo API. >>>> Portability when it comes to security is really not a big issue for me >>>> as I feel JavaEE's security is vague in any case. Besides, where ever >>>> I break portability I do so through interfaces and implementations >>>> with some "container validation". So if someone following me tries to >>>> port he'll get a "friendly" message stating he needs to make his own >>>> implementation. >>>> >>>> Quintin Beukes >>>> >>>> >>>> >>>> On Mon, Nov 16, 2009 at 7:29 PM, David Jencks >>>> wrote: >>>>> >>>>> Hi Quintin, >>>>> >>>>> On Nov 16, 2009, at 8:41 AM, Quintin Beukes wrote: >>>>> >>>>>> Hey, >>>>>> >>>>>> I basically have a bunch of roles which should each be mapped to >>>>>> different combinations of a user's "GroupPrincipals". Something like >>>>>> this: >>>>>> >>>>>> =C2=A0 =C2=A0 >>>>>> =C2=A0 =C2=A0 =C2=A0>>>>> class >>>>>> =3D"org.apache.geronimo.security.realm.providers.GeronimoGroupPrinci= pal" >>>>>> name=3D"Lamp Room"/> >>>>>> =C2=A0 =C2=A0 >>>>>> =C2=A0 =C2=A0 >>>>>> =C2=A0 =C2=A0 =C2=A0>>>>> class >>>>>> =3D"org.apache.geronimo.security.realm.providers.GeronimoGroupPrinci= pal" >>>>>> name=3D"Lamp Room"/> >>>>>> =C2=A0 =C2=A0 >>>>>> =C2=A0 =C2=A0 >>>>>> =C2=A0 =C2=A0 =C2=A0>>>>> class >>>>>> =3D"org.apache.geronimo.security.realm.providers.GeronimoGroupPrinci= pal" >>>>>> name=3D"Lamp Room"/> >>>>>> =C2=A0 =C2=A0 >>>>>> >>>>>> This means that named roles are all assigned to a user of group "Lam= p >>>>>> Room". >>>>>> >>>>>> Though doing the following I don't see these "virtual roles", only t= he >>>>>> actual group. >>>>>> =C2=A0Subject subject =3D ContextManager.getCurrentCaller(); >>>>>> =C2=A0Set principals =3D subject.getPrincipals(); >>>>> >>>>> roles are just names, not principals, so there's no way you'll see th= em >>>>> in >>>>> the Subject. =C2=A0Here's how it works, in PolicyContextGeneric: >>>>> >>>>> 1. the principal-role map specified above is fed in. >>>>> 2. the role-permission map specified by the DD or annotations is fed = in >>>>> 3. these are combined to form a principal-permission map as the app >>>>> starts >>>>> up >>>>> 4. when you test a permission (either through container access contro= l >>>>> or an >>>>> isUserInRole/isCallerInRole call) we run through the Subject's >>>>> principals, >>>>> get the PermissionCollection for that principal, and see if it implie= s >>>>> the >>>>> permission desired. >>>>> >>>>> One thing to note about this is that geronimo needs to know about the >>>>> role >>>>> and permission you're going to check. =C2=A0So the role has to be dec= lared >>>>> somewhere. =C2=A0I'm less sure about the role-ref permission... >>>>> for web apps there is an implicit role-ref permission set up mapping = the >>>>> role to itself for any role without an explicit role-ref. =C2=A0I don= 't >>>>> recall >>>>> how ejbs work, I kinda think that you have to declare all the roles y= ou >>>>> are >>>>> going to test with a role-ref. >>>>> >>>>>> >>>>>> I can see how this would be the case, though the following must >>>>>> definitely work: isCallerInRole("Personnel Admin") or EVEN >>>>>> isCallerInRole("Lamp Room"). They all return false. >>>>>> >>>>>> If I have a method annotated with @RolesAllowed({"Personnel User"}), >>>>>> then GeronimoSecurityService.isCallerAuthorized(Method method, >>>>>> InterfaceType typee) return TRUE. >>>>>> Though, GeronimoSecurityService.isCallerInRole(String role) returns >>>>>> FALSE when I query isCallerInRole("Personnel User"). >>>>> >>>>> I think this might support my idea that you have to explicitly set up= a >>>>> role-ref for any role you mean to test in an ejb. >>>>>> >>>>>> I assume somewhere the AccessControlContext isn't populated correctl= y? >>>>>> I'm not really sure how this should work, so if someone can tell me >>>>>> how this all fits together I can have a look. >>>>>> >>>>> >>>>> Let me know if the above doesn't answer your questions >>>>> >>>>> thanks >>>>> david jencks >>>>> >>>>>> Quintin Beukes >>>>> >>>>> >>>> >> >> >