Multiple Realms

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Multiple Realms

rchristy
Hello All,

I have seen the posting on Multiple Realms just a few below this one but I had a slight variation of the same question and I believe the way to do it is multiple realms.  

Right now I am using ActiveDirectory to authenticate and define my roles, but this isn't going to support permissions for roles.  So I thought I would have to add a second realm that maps roles to permissions.  So I tried to use the IniRealm and left the users empty (I don't want to have to duplicate all users/passwords in each Realm).  However this didn't seem to work.  So is it possible to have one Realm authenticate and another Realm map only roles (the same roles as defined in the first realm) to permissions?  And if this is possible, does an existing realm in shiro already do this or is this something that would require me to implement a realm for.  

The idea here is that the same Subject instance would have user/passwords/roles defined in one realm and permissions for these roles defined in a different realm.  Is this possible or am I misunderstanding the use of multiple realms.

Thanks

Rich
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

rchristy
OK looking into this a bit more, I see all i really need to do is make sure queryForAuthorizationInfo() implementation I made also implements the permissions (i.e. string and/or objects) when it builds the AuthorizationInfo.  I have already implemented my own version of ActiveDirectoryRealm that has a slightly different implementation than the shiro version.  So in my implementation of this, I can select a second data source that allows me to pull in the permissioning at the same time it authenticates agains ActiveDirectory when queryForAuthorizationInfo is invoked.  Is this how it is expected to work in shiro?

Thanks,

Rich
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

Les Hazlewood-2
In reply to this post by rchristy
Hi Rich,

On Thu, Jan 21, 2010 at 11:26 AM, rchristy <[hidden email]> wrote:
> use the IniRealm and left the users empty (I don't want to have to duplicate
> all users/passwords in each Realm).  However this didn't seem to work.

Yeah, roles don't have any value unless they're associated with user accounts
somehow.  The IniRealm doesn't know how to interact with user data outside of
its own format.

> is it possible to have one Realm authenticate and another Realm map only
> roles (the same roles as defined in the first realm) to permissions?  And if
> this is possible, does an existing realm in shiro already do this or is this
> something that would require me to implement a realm for.
>
> The idea here is that the same Subject instance would have
> user/passwords/roles defined in one realm and permissions for these roles
> defined in a different realm.  Is this possible or am I misunderstanding the
> use of multiple realms.

Yes, this is possible - but do you want to make the
roles-to-permissions association at startup for all roles?  If so, one
Realm (that associates permissions to roles) might need to find out
what the roles are, possibly by communicating with the other Realm
that does the authentication.

Or do you want to make this association only after the user has
authenticated and you know what the user's roles are?

- Les
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

Les Hazlewood-2
In reply to this post by rchristy
Yep, this is the solution behind the 2nd question in my previous email :)

Your implementation of that method would find out the roles assigned
to the user, and then you could use whatever you wanted to acquire
permissions for those roles.

Using an IniRealm as an internal helper component should work in this
case because roles and their permissions are stored in SimpleRole
objects keyed by role name.  If you use IniRealm (a subclass of
SimpleAccountRealm), you could call the SimpleAccountRealm.getRole()
object, get its permissions (simpleRole.getPermissions()) and just add
those directly to the AuthorizationInfo object you will return from
that method.

You could even have a nice configuration passthrough method on your
ActiveDirectoryRealm:

setPermissionAssignments( String roleToPermsConfig) {
    String config = "[roles]\n" + roleToPermsConfig;
    Ini ini = new Ini();
    ini.load(config);
    this.iniRealm = new IniRealm(ini);
}

Then reference the iniRealm in your queryForAuthorizationInfo method
to pull the Role objects with their permissions.

HTH,

Les

On Thu, Jan 21, 2010 at 12:57 PM, rchristy <[hidden email]> wrote:

>
> OK looking into this a bit more, I see all i really need to do is make sure
> queryForAuthorizationInfo() implementation I made also implements the
> permissions (i.e. string and/or objects) when it builds the
> AuthorizationInfo.  I have already implemented my own version of
> ActiveDirectoryRealm that has a slightly different implementation than the
> shiro version.  So in my implementation of this, I can select a second data
> source that allows me to pull in the permissioning at the same time it
> authenticates agains ActiveDirectory when queryForAuthorizationInfo is
> invoked.  Is this how it is expected to work in shiro?
>
> Thanks,
>
> Rich
> --
> View this message in context: http://n2.nabble.com/Multiple-Realms-tp4434653p4435273.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

rchristy
In reply to this post by rchristy
I am basically working on an enterprise Authentication module that will run on its own and I am trying to use shiro for that (so far very successfully).  Right now I want to authenticate against Active Directory but house permissions based on roles as well as users in another data source (most likely a database).   For cases that just map roles--to-permissions, that would be at start up since my roles are somewhat fixed.  However the only way I was able to figure out how to do specific user based permissions was to also read it in at start up and have these cached ahead of the user logging in.  For these cases, the data source would contain the userid so I could make associations, but not any password information.  So my plan was to have my ActiveDirectoryRealm implementation use Active Directory to get populate the getRoles() but use this second data source to determine the permissions based on the roles/userid for the user as they login.

However I am open to other suggestions on how to implement this.  

Thanks,

Rich
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

rchristy
Sorry Les, I am post behind you.  So this sounds like I am on the right track, thanks for the help.

Rich
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

Les Hazlewood-2
No problem.  Just to be clear though, two configured realms would have
worked just as well.  Your 2nd Realm would subclass AuthorizingRealm
and it would always return false for the supports(AuthenticationToken)
implementation since you never want it to participate in
authentication.

Then you would implement the doGetAuthorizationInfo method to pull in
roles for that user however you want.

The benefit of this approach rather than having 1 realm do both is
that it is a little less coupled - you could swap out either realm
implementation for another without impacting the other.
Authentication and Authorization are orthogonal processes and almost
never require dependencies between the two.

Regards,

Les

On Thu, Jan 21, 2010 at 3:09 PM, rchristy <[hidden email]> wrote:
>
> Sorry Les, I am post behind you.  So this sounds like I am on the right
> track, thanks for the help.
>
> Rich
> --
> View this message in context: http://n2.nabble.com/Multiple-Realms-tp4434653p4436055.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

rchristy
aaahhhh, I like that approach better.  That way my second realm is more pluggable.  

Thanks again for your help.

Rich
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

Les Hazlewood-2
Yep, that's my preferred approach too if possible - a little cleaner :)

- Les

On Thu, Jan 21, 2010 at 3:47 PM, rchristy <[hidden email]> wrote:

>
> aaahhhh, I like that approach better.  That way my second realm is more
> pluggable.
>
> Thanks again for your help.
>
> Rich
> --
> View this message in context: http://n2.nabble.com/Multiple-Realms-tp4434653p4436244.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

gcollins
In reply to this post by Les Hazlewood-2
How can you use "getRole" from SimpleAccountRealm? "getRole" is protected.

I see there is a RolePermissionResolver defined in the code...but no class (other than the ModularRealmAuthenticator) makes use of it (even though anything that extends AuthorizationRealm is "RolePermissionResolverAware", like the ActiveDirectoryRealm). Is this not meant to be used going forward?

Some background to the problem I am trying to solve. I wanted to use the ActiveDirectoryRealm to auth and get groups, then use the default IniRealm to convert roles to permissions (I just wanted to set up something simple to show I could do ActiveDirectory authentication and authorization). The solution I found was more convoluted than I expected it to be. Did I miss something here (see below)?

thanks,
Gareth

public class SimpleAccountRolePermissionResolver implements
                RolePermissionResolver {
       
        private volatile SimpleAccountRealm simpleAccountRealm;
        private volatile Method getRoleMethod;
       
        public SimpleAccountRolePermissionResolver() {
               
        }
       
        // I set simpleAccountRealm to $iniRealm in the ini file
        public void setSimpleAccountRealm(SimpleAccountRealm simpleAccountRealm) {
                this.simpleAccountRealm = simpleAccountRealm;
                try {
                        // awful hack to get around the protected permissions of getRole
                        getRoleMethod = SimpleAccountRealm.class.getDeclaredMethod("getRole", String.class);
                        getRoleMethod.setAccessible(true);
                } catch (Throwable t) {
                        // some action
                }
        }

        @Override
        public Collection<Permission> resolvePermissionsInRole(String roleString) {
                try {
                        SimpleRole role = (SimpleRole) getRoleMethod.invoke(simpleAccountRealm, roleString);
                        return role.getPermissions();
                } catch (Throwable t) {
                        // some action
                }
                return new HashSet<Permission>();
        }
}

-----------

public class MyActiveDirectoryRealm extends ActiveDirectoryRealm {

        // Why doesn't the standard ActiveDirectoryRealm take
        // advantage of the RolePermissionResolver like this?
        @Override
        protected AuthorizationInfo buildAuthorizationInfo(Set<String> roleNames) {
                RolePermissionResolver resolver = this.getRolePermissionResolver();
                SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
                if (resolver != null) {
                        for (String role: roleNames) {
                                info.addObjectPermissions(resolver.resolvePermissionsInRole(role));
                        }
                }
                return info;
        }
}


Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

Mike K
In reply to this post by rchristy
Les, I am actually looking at implementing something similar. How does one make sure that principals are translated between two realms?
Internally controlled realms can be more permissive and use UUID (or DBID) as the principal id.
LDAP uses a DN (there could be several LDAP directories). Any thoughts on keeping this all from becoming a mess?
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

Manoj Khangaonkar
Hi,

Seems to me that you needs to maintain a map somewhere that tells your realms

that principal1, DN1, uid1 , dbid1 are the same person.

On authentication, doGetAuthenticationInfo method of your Realm
returns AuthenticationInfo which
not 1 principal but a PrincipalCollection. You could populate the
PrincipalCollection with all the Principals.

Manoj

On Mon, Oct 24, 2011 at 8:24 AM, Mike K <[hidden email]> wrote:

> Les, I am actually looking at implementing something similar. How does one
> make sure that principals are translated between two realms?
> Internally controlled realms can be more permissive and use UUID (or DBID)
> as the principal id.
> LDAP uses a DN (there could be several LDAP directories). Any thoughts on
> keeping this all from becoming a mess?
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/Multiple-Realms-tp4434653p6925397.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>



--
http://khangaonkar.blogspot.com/
Reply | Threaded
Open this post in threaded view
|

Re: Multiple Realms

armandoxxx
In reply to this post by Les Hazlewood-2
Thank you for this .. this was my latest idea ... I've been strugling with
docs and api for possible sollutions for 2 days now ...

Regards

Armando



--
Sent from: http://shiro-user.582556.n2.nabble.com/