Sunday, November 25, 2007

 

Implementing External Authorization in BPM and ECM Products (Part One)

Phil Gilbert, CTO of Lombardi Software, John Newton, CTO of Alfresco, Craig Randall, Bex Huff and others have let me get away with ranting about XACML without stepping up to prove how easy it is...



This will be first in a three part post on techniques that enterprise software vendors can use to externalize authorization from their products. If you aren't familiar with XACML, please visit the XACML specification.

For this example, I will use Liferay Enterprise Portal since the source code is 100% freely available. I am willing to do the same within a BPM context against Intalio, but I couldn't locate the source code for the BPM engine.

It is important to acknowledge that Brian Chan and others from Liferay acknowledged the importance of the ability to externalize security as part of the 4.0 version. Versions prior to this didn't have this capability and I will leave it to Brian and others to talk about design considerations. Anyway, there is a good document on what needs to occur in order to externalize security from liferay here. You will notice that there is a single Java interface named PermissionChecker that you need to extend with your own custom implementation. Here is where XACML can be nicely integrated. In the next posting, I will show you exactly what code needs to go here.

The thing that we should focus on first is in how to get the metadata describing what an application and roles are externalized. If your particular product stores it within a relational database, then the task is relatively straightforward in that you can create a routine that creates a file that can be exported to an XACML PAP. It should look something like this:

<organization>
<applicationgroups>
<applicationgroup>
<applicationgroup_name>Liferay</applicationgroup_name>
<applicationgroup_desc>Liferay</applicationgroup_desc>
<applications>
<application>
<application_name>portlets</application_name>
<application_desc>portlets</application_desc>
<application_contact_info>James McGovern</application_contact_info>
<application_server>Weblogic</application_server>
<ispepconfigured>YES</ispepconfigured>
<policycmbalg>1</policycmbalg>
<obligationid>3</obligationid>
<resources>
<resource>
<resource_name>search</resource_name>
<resource_desc>search</resource_desc>
<application_id>portlets</application_id>
<resourcetype>
<name>UNTYPE</name>
<belongsto>Global</belongsto>
<attributes></attributes>
<actions></actions>
</resourcetype>
<policycmbalg>1</policycmbalg>
<obligationid>3</obligationid>
<parent_resource>
Liferay:portlets
</parent_resource>
</resource>
<resource>
<resource_name>VIEW</resource_name>
<resource_desc>VIEW</resource_desc>
<application_id>portlets</application_id>
<resourcetype>
<name>ACTION</name>
<belongsto>Global</belongsto>
<attributes></attributes>
<actions></actions>
</resourcetype>
<policycmbalg>1</policycmbalg>
<obligationid>3</obligationid>
<parent_resource>
Liferay:portlets:search
</parent_resource>
</resource>
</resources>
</application>
</applications>
</applicationgroup>
</applicationgroups>
<roles>
<role>
<rolename>All Users</rolename>
<roledes>All Users</roledes>
<rolestatus>STATIC</rolestatus>
<parentrole_name>All Users</parentrole_name>
<roleagaptype>AG</roleagaptype>
<roletype>
<name>Default</name>
<belongsto>Global</belongsto>
<attributes></attributes>
</roletype>
<rules></rules>
<rules-conjunction>
<rule-conjunction></rule-conjunction>
</rules-conjunction>
</role>
<role>
<rolename>UnKnown Users</rolename>
<roledes>
UnKnown Users for users,who are not mapped
</roledes>
<rolestatus>STATIC</rolestatus>
<parentrole_name>Liferay</parentrole_name>
<roleagaptype>AG</roleagaptype>
<roletype>
<name>Default</name>
<belongsto>Global</belongsto>
<attributes></attributes>
</roletype>
<rules></rules>
<rules-conjunction>
<rule-conjunction></rule-conjunction>
</rules-conjunction>
</role>
<role>
<rolename>User</rolename>
<roledes>User</roledes>
<rolestatus>STATIC</rolestatus>
<parentrole_name>Liferay:portlets</parentrole_name>
<roleagaptype>AP</roleagaptype>
<roletype>
<name>Default</name>
<belongsto>Global</belongsto>
<attributes></attributes>
</roletype>
<rules></rules>
<rules-conjunction>
<rule-conjunction></rule-conjunction>
</rules-conjunction>
</role>
</roles>
<users>
<user>
<username>Test HKG 1</username>
<useremail>null</useremail>
<userbelongsto>Liferay:portlets</userbelongsto>
<usertype>
<name>Default</name>
<belongsto>Global</belongsto>
<attributes></attributes>
</usertype>
</user>
</users>
<userrolemaps>
<userrolemap>
<rolename>User</rolename>
<username>Liferay:portlets:Test HKG 1</username>
<parentrolename>Liferay:portlets</parentrolename>
<usertype>AP</usertype>
<contextfqn>Global Context:Global Context</contextfqn>
<bundlefqn>Global:Default</bundlefqn>
</userrolemap>
</userrolemaps>
<contexts></contexts>
<rolebundles>
<rolebundle>
<rolebundletname>Default</rolebundletname>
<rolebundletdesc>DEFAULT ROLE BUNDLE</rolebundletdesc>
<rolebundleparent>Global</rolebundleparent>
</rolebundle>
<rolebundle>
<rolebundletname>Default</rolebundletname>
<rolebundletdesc>DEFAULT ROLE BUNDLE</rolebundletdesc>
<rolebundleparent>Global</rolebundleparent>
</rolebundle>
</rolebundles>
<usertypes>
<usertype>
<name>Default</name>
<belongsto>Global</belongsto>
<attributes></attributes>
</usertype>
</usertypes>
<roletypes>
<roletype>
<name>Default</name>
<belongsto>Global</belongsto>
<attributes></attributes>
</roletype>
</roletypes>
<grouptypes>
<grouptype>
<name>Default</name>
<belongsto>Global</belongsto>
<attributes></attributes>
</grouptype>
</grouptypes>
</organization>


If you want to generate it directly from the database, Liferay provides the data model here. If you have questions on what I posted to date, please either leave a comment and/or trackback as I want to make sure that my examples are clear enough for others to leverage...






<< Home
| | View blog reactions


This page is powered by Blogger. Isn't yours?