Aliaspooryorik
ColdFusion ORM Book

Fusebox NOXML permissions

One of things I miss about the XML approach is the permissions attribute for circuit and fuseaction.  My solution is to use MetaData, so you could do something like:


<cfcomponent extends="com.ControllerCircuit"
output="false"
hint="I am the foobar circuit">


<cffunction name="home"
access="public"
output="false"
permissions="Developer,Designer">

<cfargument name="myFusebox" />
<cfargument name="event" />
... do something ...
</cffunction>

<cffunction name="prefuseaction"
access="public"
output="true"
hint="I process pre fuseaction execution">

<cfargument name="myFusebox" />
<cfargument name="event" />

<cfset arguments.event.xfa( "login", "foobar.login" )  />
<cfset super.prefuseaction( myFusebox, event ) />

</cffunction>

</cfcomponent>

Note the permissions attribute I've added to the home fuseaction. Each "circuit cfc" extends ControllerCircuit.cfc and calls it's prefuseaction method.

ControllerCircuit.cfc


<cfcomponent output="false"
hint="I am the Controller Circuit superclass">


<cffunction name="prefuseaction"
access="public"
output="true"
hint="I process pre fuseaction execution">

<cfargument name="myFusebox" />
<cfargument name="event" />

<cfset var index = 0 />
<cfset var authorised = False />
<cfset var fuseMetaData = getMetaData( this ).functions />
<cfset var User = Application.BeanFactory.getBean( "MemberService" ).getCurrentUser() />

<cfloop from="1" to="#ArrayLen( fuseMetaData )#" index="index">
<!--- myFusebox.getCurrentFuseaction() not available in production mode so using myFusebox.ThisFuseaction --->
<cfif Compare( fuseMetaData[ index ].name, arguments.myFusebox.ThisFuseaction ) EQ 0>
<cfif StructKeyExists( fuseMetaData[ index ], "permissions" )>
<cfset allowedroles = fuseMetaData[ index ].permissions />
</cfif>
<cfbreak />
</cfif>
</cfloop>
<cfset authorised = User.HasAnyRole( allowedroles ) />
<cfif NOT authorised>
<cfset arguments.myFusebox.relocate( xfa="login" ) />
</cfif>

</cffunction>

</cfcomponent>

The above code doesn't make use of ColdFusion's inbuilt security methods. Personally I think cflogin it is more trouble than it's worth, and I'd much rather have a User object, but if you really want to you can use cflogin with a few minor alterations you can:


<cfcomponent extends="com.ControllerCircuit"
output="false"
hint="I am the foobar circuit">


<cffunction name="home"
access="public"
output="false"
roles="Developer,Designer">

<cfargument name="myFusebox" />
<cfargument name="event" />
... do something ...
</cffunction>

<cffunction name="prefuseaction"
access="public"
output="true"
hint="I process pre fuseaction execution">

<cfargument name="myFusebox" />
<cfargument name="event" />

<cfset arguments.event.xfa( "login", "foobar.login" )  />
<cfset super.prefuseaction( myFusebox, event ) />

</cffunction>

</cfcomponent>

Note the roles attribute (which works in partnership with cflogin) I've added to the home fuseaction in place of my custom permissions attribute. As before, each "circuit cfc" extends ControllerCircuit.cfc and calls it's prefuseaction method.

ControllerCircuit.cfc


<cfcomponent output="false"
hint="I am the Controller Circuit superclass">


<cffunction name="prefuseaction"
access="public"
output="true"
hint="I process pre fuseaction execution">

<cfargument name="myFusebox" />
<cfargument name="event" />

<cfset var index = 0 />
<cfset var authorised = False />
<cfset var fuseMetaData = getMetaData( this ).functions />

<cfloop from="1" to="#ArrayLen( fuseMetaData )#" index="index">
<!--- myFusebox.getCurrentFuseaction() not available in production mode so using myFusebox.ThisFuseaction --->
<cfif Compare( fuseMetaData[ index ].name, arguments.myFusebox.ThisFuseaction ) EQ 0>
<cfif StructKeyExists( fuseMetaData[ index ], "roles" )>
<cfset allowedroles = fuseMetaData[ index ].roles />
</cfif>
<cfbreak />
</cfif>
</cfloop>
<cfset authorised = IsUserInAnyRole( allowedroles ) />
<cfif NOT authorised>
<cfset arguments.myFusebox.relocate( xfa="login" ) />
</cfif>

</cffunction>

</cfcomponent>

I haven't tried this on a high traffic website but it seems to work well. My thoughts are to store the MetaData in the application scope as each circuit is called to improve performance. Fusebox XML stored this in myFusebox.getApplication().circuits[ mycircuitname ].permissions. In the no XML variation this structure this exists, it just has blank values.

It is worth pointing out that you can't use the roles attribute without cflogin - if you do then you'll get the exception "The current user is not authorized to invoke this method."

Feedback welcome as always!


3 comments

  1. In the cfc-as-circuit implementation, fuse-actions are component methods, and component methods already have a 'roles' attribute which you can use to limit access to method execution. (You get an 'UnauthorizedAccessException' if the current user's role isn't in the comma-delimited list you provide).

    Seems like it would suit your needs, unless I'm mistaken?

    Cheers,
    Jeff D.

    Comment by Jeff D. – February 08, 2009
  2. Hi Jeff, as I mentioned I didn't want to use cflogin (for various reasons) in my application so can't use the roles attribute, however as you say, if you want to use cflogin then the roles attribute will work. I'd still use the metadata approach if I was using cflogin to check permissions in the prefusaction rather then catch the exception.

    There is a bit more discussion on my approach at which you may be interested to read in Fusebox Yahoo Groups thread on this: tech.groups.yahoo.com/group/fusebox5/message/4109

    Comment by John Whish – February 08, 2009
  3. @Jeff, I've updated my post to show both approaches and hopefully explain the pros and cons of each approach.

    Thanks for you feedback :)

    Comment by John Whish – February 09, 2009

Leave a comment

If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

Please note: If you haven't commented before, then your comments will be moderated before they are displayed.

Please subscribe me to any further comments
 

Search

Wish List

Found something helpful & want to say ’thanks‘? Then visit my Amazon Wish List :)

Categories

Recent Posts