I had a great conversation with Alex Karasulu at Apachecon about integrating TripleSec into geronimo as a JACC provider. I think this will be pretty easy to do and provide a very powerful security management capability for geronimo. I'll try to describe my understanding of our conclusions about what needs to be done. My understanding of TripleSec is based entirely on Alex's brief descriptions so any inaccuracies should be blamed entirely on me :-)

Data Model

The TripleSec datamodel needs some changes to fit with java permissions and the j2ee permissions categories of unchecked, excluded, and role-mapped. To review for those who may not have reviewed their JACC recently :-) the unchecked and excluded permissions apply to all users without regard to who they are or what roles they might be in whereas the role-mapped permissions grant permission based on the users current roles.

- permissions. IIUC the current TS permission model uses String.equals to implement Permission.implies(Permission). This doesn't work well with things like web permissions where you can be granted permission to see /context-root/public/* but excluded from seeing /context-root/public/area/secret/*. I think that it will be much more powerful to support storing actual java Permission objects in LDAP and delegating the implies to the actual Permission implementation. Use of Permission.implies is required for a JACC implementation. I think simply serializing the permissions and saving the bytes as well as saving the toString() name for identification will work OK for an initial implementation: Alex suggested using StateFactory and ObjectFactory for a more sophisticated implementation that would store more meaningful info.

-role-mapped permissions are supported well by TS role-principal mapping and profiles.

- unchecked permissions are not currently supported by TS. I think these can be supported by having an "unchecked" role and granting it to all users.

- excluded permissions are not currently supported by TS. I think the best way to support them is by modifying Profile to include a set of denied roles along with the existing granted roles and granted and denied individual permissions. The excluded permissions can be modeled as a role denied to everyone.

With this proposed change Profile would contain a userId, an applicationId, a set of granted roles, a set of denied roles, a set of granted permissions, and a set of denied permissions.

The effective permissions set needs to contain both granted and denied permissions since a denied permission will generally not exactly match any granted permission. So, the granted permissions would be the union of permissions from the profile's granted roles together with the individual granted permissions, and the denied permissions would be the union of permissions from the profiles denied roles together with the individual denied permissions.

The TS LoginModule needs to generate a subject from which the granted and denied permissions can be extracted for each applicationId. The simplest way I can think of to do this is to use a TSPrincipal that contains a map of applicationId to an object containing the granted and denied permissions.

The JACC policyContextId seems to correspond well to the TS applicationId.

JACC integration.

We can divide this into runtime policy enforcement and deployment time policy configuration.

-runtime. Following normal methods the user logs into a security realm that uses a TSLoginModule producing a TSPrincipal containing the effective permissions as described above. When a permissions check is done, as usual the decision is delegated to the PolicyConfiguration for the policyContextId: this checks the permission in question against first the denied permissions and (if not denied) the granted permissions, per the following simple code:

public boolean implies(ProtectionDomain domain, Permission permission) {

        Principal[] principals = domain.getPrincipals();
        if (principals.length == 0) return false;

        for (int i = 0; i < principals.length; i++) {
            Principal principal = principals[i];
            if (principal instanceof TripleSecPrincipal) {
PermissionsHolder permissionsHolder = ((TripleSecPrincipal)principal).getPermissionsHolder(contextID);

                Permissions denied = permissionsHolder.getDenied();
                if (denied.implies(permission)) return false;

                Permissions granted = permissionsHolder.getGranted();
                //only look for one TripleSec permission
                return granted.implies(permission);

            }
        }
        // if no TripleSec principal found, deny access.
        return false;
    }

This part will just work in geronimo after configuring a security realm using the TSLoginModule and specifying TSPolicyConfigurationFactory as the JACC provider.


-deployment time. Currently geronimo waits until the application starts to install the permissions into the JACC provider. I think this is primarily because we don't have a persistent store for these permissions, although the spec might have something to say about this as well (I don't remember). Since TS definitely has a persistent store, I think it would be more appropriate to install the spec permissions when the application is converted into a geronimo module (car file). This gives the security administrators time to configure the users profiles. I don't know when it would be appropriate to remove an applications permission info from TS, nor do I have an idea how redeployment with changed permissions might work. I'm hoping that after we get the basics described above done it will be clearer how to deal with application evolution.

----------------------

I spent a few minutes and wrote up the start of most of the classes needed for the integration. I put them at https://svn.apache.org/ repos/asf/geronimo/sandbox/triplesec

TSPolicyConfigurationFactory --- this is probably complete.
TSPolicyConfiguration -- the implies method is probably complete. The methods for adding and removing permissions need to be hooked up to TS. It's not entirely clear to me exactly what the open(remove) method should do. This is basically the application evolution question I mentioned above, and we probably don't have to answer it until we get everything else working. TSPrincipal -- this is a very simple implementation of something that meets the needs of the TSPolicyConfiguration. If I understaood Alex correctly the existing TSPrincipal gets updated when the data in LDAP changes. I'm hoping that the additional complexity of having both granted and denied permissions will not make this significantly harder.

TSSecurityBuilder. This is a Geronimo Security builder. Basically it has no knowledge of TS whatsoever and just uses the JACC interfaces to install the spec defined security info into the PolicyConfigurations during deployment. There are a couple of methods that I don't know how to implement, and they remind me that at last years ApacheCon Simon Godik pointed out that all Subjects used in geronimo should be derived by logging some user into the appropriate security realm. If we had taken his good advice these methods would not be there to cause problems. I think its time we changed to this model. Meanwhile I don't think that the implementation hole will affect TS integration" its used for specifying default users and run-as subjects.

The TSSecurityBuilder IMO should be moved into geronimo core since it can be used with any jacc provider that provides a persistent store. The other classes I think should move to TS. I plan to be working with Alex and anyone else who is interested over the next few weeks to get this into a working state. Ideally I'd like to see it as a geronimo plugin released with geronimo 1.2.

I also opened GERONIMO-2497 to help tracking progress on this.


------------------

On a mostly unrelated note I recall that jetspeed2 has a security administration portlet app for their security system that has some feature overlap with TS. I wonder if it would be possible to use this as a start for developing a web front end for TS.

thanks
david jencks




Reply via email to