Learn About Doug!
View Doug Boude's online resume
updated 4/22/2009

View Doug Boude's profile on LinkedIn
Link to me!

Follow Doug Boude on Twitter
Follow me!

Be Doug's friend on Facebook
Befriend me!
(I promise not to follow you home)
Contact Doug!
OO Lexicon
Chat with Doug!
Recent Entries
You may also be interested in...
Florida web site design



Czech your Page Rank!
Check Page Rank of any web site pages instantly:
This free page rank checking tool is powered by Page Rank Checker service
Surf's Up!
Visit Egosurf.org and massage YOUR web ego!
My Score: 9,001
Doug's Books

Read (and recommend)

  • Men are from Mars, Women are from Venus
  • The Wisdom of Crowds: Why the Many Are Smarter Than the Few and How Collective Wisdom Shapes Business, Economies, Societies and Nations
  • Blink: The Power of Thinking Without Thinking
  • Head First Design Patterns
  • Transact-SQL Programming
  • What's So Amazing About Grace?
  • Just So Stories (Rudyard Kipling collection)

Reading

  • Prayer: Does it Make Any Difference?
  • Data Mining (Practical Machine Learning Tools and Techniques)
<< July, 2009 >>
SMTWTFS
1234
567891011
12131415161718
19202122232425
262728293031
Search Blog

Recent Comments
Re: Equivalent of SQL "TOP X" in Oracle (by Azzedo at 7/01 4:39 PM)
Re: Small But Seriously Irritating Export to Excel Issue (by dougboude at 6/30 2:47 PM)
Re: Small But Seriously Irritating Export to Excel Issue (by Shannon Hicks at 6/30 1:41 PM)
Re: Disappearing IE Popup Window During Save/Open Dialog (by James Moberg at 6/26 7:17 PM)
Re: Buying a New Home in San Antonio (by ike at 6/26 2:58 PM)
Re: SQL Forward Engineering with Visio 2003 Professional (by Matthew at 6/17 2:33 PM)
Re: Special Character/Unicode Issue in Ajax Data Retrieval (by matt at 6/15 3:34 AM)
Re: My Twelve Steps to a Coldbox App (by Dutch Rapley at 6/12 1:34 PM)
Re: My Twelve Steps to a Coldbox App (by dougboude at 6/12 12:09 PM)
Re: My Twelve Steps to a Coldbox App (by Dutch Rapley at 6/12 11:52 AM)
Categories
Archives
Photo Albums
Funnies (5)
Family (3)
RSS

Powered by
BlogCFM v1.11

03 July 2008
Basic Security in Fusebox 5.5.x (sans XML)
I have recently begun a project using the latest version of Fusebox (5.5.1). This is my second forray into Fusebox 5x, but the first one wasn't much more than a hello world for my own benefit. This time, I'm taking the "sans XML" approach and using FB in its MVC arrangement to build an application that is primarily a data management tool utilizing Java proxies exclusively as its means to communicate with a backend Oracle database. So, as I learn things along the way, I'm going to be sharing them as blog posts in order to possibly give others some stepping stones as they traverse their own FB "sans XML" J-curve.

I should also say that I am coming to Fusebox 5.5 after having exclusively used Model-Glue v2 for the past year and a half or so. Since one's natural approach is to try and equate what you already know from your current framework of choice to the one you are now learning, that is what I will be doing as well, so you may often see me reference things in Model-Glue terminology to help bridge the knowledge gap. In fact, one of the first things I did was to rename my fuseaction to "event", just to make me feel a little more at home. :)

Okay, so one of the first things I needed to create for this app was some basic security; if the user is not logged on, they don't get past the first page, period. Though there are always many solutions to the same challenge, following is my own approach to the matter.

Step 1 is find the best place within the Fusebox event lifecycle (which I STILL don't fully know, nor could I find any clear documentation on) in which to "intercept and potentially redirect" our call. Basically, before our user arrives at their destination page, we want to see if it is a secured page (which all of mine are except for the login) AND if the user has already successfully authenticated, then redirect them to the login page if needed.

In order to maintain the user's state (keep track of whether or not they logged in, store their personal info in a handy, globally available package), I created a User.cfc that I make sure has been instantiated with an initial 'loggedin' setting of false (this is built into the CFC's init method), and placed into the session scope. In Fusebox 5.5.1, the most appropriate place to do this that I found is in the Application.CFC's "onRequestStart" method. Mine looks like this:

<cffunction access="public" name="onRequestStart" output="false" returntype="void" hint="I am the code to execute at the beginning of a request. ">
    <cfargument name="targetPage" />
    <cfset super.onRequestStart(arguments.targetPage) />
    <!--- formerly in fusebox.init.cfm --->
    <cfset self = myFusebox.getSelf() />
    <cfset myself = myFusebox.getMyself() />

    <cfif not structkeyexists(session,"user")>
        <cfset session.user = createObject( 'component','model.user').init()/>
    </cfif>
   
    <!--- making our user object available in the event bean. Event is created by Fusebox and is available to us at this point. --->
    <cfset event.setValue("user",session.user) />
</cffunction>


Notice that we are doing a call to "super.onRequeststart". This is because our Application.cfc is extending (<cfcomponent extends="fusebox5.Application" output="false">) Fusebox's Application.cfc, so we need to make sure the framework gets to execute its onRequestStart as well. If we didn't make the 'super' call, our method would override FB's method and things just wouldn't go well at all.

Okay, so now with every request, I ensure that I have at LEAST an empty user object in session. The remainder of the onRequestStart method places my user object into a handly little bucket Fusebox provides us called (thankfully) 'Event'. This works very well for me, as in Model-Glue it's ALL ABOUT the event, my brutha from anotha mutha. By putting user into 'event', i can access it from anywhere else in my application WITHOUT having to talk directly to session ( a big OO No No, for the most part).

Now, the request still has not yet arrived at its destination page, and Fusebox has another file yet to process before it renders any content: Fusebox.init.cfm.

Though I tried madly to do all of my intercept and redirect within application.cfc, alas I could not make it work. Feedback from Mr. Corfield affirmed that indeed application.cfc was not the best place to do what I was trying to do, anyway, and directed me to fusebox.init.cfm as the most proper location to perform any needed manipulation of the target fuseaction. Here is the content of my fusebox.init.cfm file:

<!--- ************ SECURITY CHECK! ***************** --->
<!--- if we're not authenticated and our current fuseaction is NOT our default fuseaction (in order to avoid a dreaded infinite loop), make it so --->
<cfif (not structkeyexists(session,"user") OR not session.user.getLoggedin()) AND attributes.fuseaction IS NOT myFusebox.getApplication().defaultfuseaction>
    <!--- if user is not logged in, replace the current fuseaction/event name with our default --->
    <cfset myFusebox.relocate(url=myFusebox.getApplication().myself & myFusebox.getApplication().defaultfuseaction) />
</cfif>



As you can see, i'm doing a simple check of the user object and the target fuseaction. If the user isn't logged in (or user object doesn't exist for whatever reason) AND our target fuseaction is something OTHER than our default fuseaction (login), then we're leveraging the fusebox 'Relocate' method to force the user to our login page.

That's it, it's that simple. If I had to do fuseaction level security, or individual page security, I think I'd probably STILL perform those actions at these exact same locations, only I'd be adding in additional checks for the user's roles and the fuseaction's security level.

Feedback on my approach solicited. :)

Doug out

 

UPDATE TO PREVIOUS POST (7/9/08)

Based on the comments I received, I made a little time to pursue the route I had proposed for implementing role/fuseaction based security and found that I could do it easily without having to add any more controllers or fuseactions. Building on all of the code above, I simply added to my user object a 'Roles' variable that contains a list of the authenticated user's roles. I then added to my global configuration bean an item 'publicFuseActions' that contains a list of the fuseactions I am NOT securing (since those are far fewer than the ones I AM securing...I could've easily reversed the contents of this list to contain FAs that ARE secured). Lastly, I made a modification to the security check in my fusebox.init.cfm to evaluate the following:

(

the user is NOT logged in

OR

user IS logged in AND the requested fuseaction IS a secure one AND the authenticated user does NOT have the appropriate role

)

AND

our requested fuseaction is NOT our default fuseaction

If the entire statement above evaluates to true, then our user needs to be redirected to the login page.

Here is my fusebox.init.cfm that accomplishes the above logic:

 

<cfif ((not structkeyexists(session,"user") OR not session.user.getLoggedin()) OR (listfindnocase(application.globals.config.getConfigSetting("publicFAs"),attributes.fuseaction) eq 0 AND listfindnocase("Admin",session.user.getRoles()) eq 0)) AND attributes.fuseaction IS NOT myFusebox.getApplication().defaultfuseaction>
 <cfset myFusebox.relocate(url=myFusebox.getApplication().myself & myFusebox.getApplication().defaultfuseaction) />
</cfif>

 

Again, I have to ask what would be the motivation/need to create additional controllers and fuseactions to perform security/role based fuseaction routing when the single IF statement above, strategically placed, accomplishes it just fine? Am I over-simplifying things? (or is it really just that simple?  ) . If I wanted to get even more elaborate, such as routing based on role, or a diversity of messages to match the situation, I would probably add a message dictionary to my global config bean and replace my growing IF statement with a call to a global security object that would perform appropriate evaluations and return the needed responses for me to execute an appropriate redirect and message. One more object in my model that I create as a singleton and have available to my fusebox.init.cfm...why complicate it any more than that? Again, input solicited.

Doug out. again.

 




Posted by dougboude at 1:51 PM | PRINT THIS POST! |Link | 5 comments
Subscription Options

You are not logged in, so your subscription status for this entry is unknown. You can login or register here.

Re: Basic Security in Fusebox 5.5.x (sans XML)
Here's my $0.02 on how I would handle your site security.

I would have 2 'controller' circuits. The first one would be the default 'app' circuit. This circuit would have 2 Fuseactions: 1) Show the home page (which has a login form), and 2) Authenticate Login (which validates the credentials).

I would then create an additional circuit (let's call it 'foo') that contains all of the really important fuseactions for your site. In the /controller/foo.cfc file, I would then have a function named 'prefuseaction' which checks to ensure the user has logged in properly. If they haven't, then they would get redirected back to the home page.

The 'prefuseaction' function in your foo.cfc file will execute prior to any fuseaction in the foo circuit. I hope that helps!
Posted by Damon Gentry on July 3, 2008 at 2:35 PM

Re: Basic Security in Fusebox 5.5.x (sans XML)
@gentry: forgive my naivetee, but isn't that a lot more work and code? Just curious, but what's the justification for the additional controllers and code? What's the payoff? What does it allow me that I need and don't have with my approach? I'm sincerely interested! And thanks for the alternative suggestion!
Posted by dougboude on July 3, 2008 at 7:31 PM

Re: Basic Security in Fusebox 5.5.x (sans XML)
@Doug
I wouldn't say its a lot more work to do what Damon suggested.

The payoff would be a controller that anything you didn't need a security check could go into. just shooting blindly, i would say your home page, your login page, later when/if you add a privacy statement or something along those lines. And, this wouldn't require a change to your security check.
Posted by Matt Jones on July 7, 2008 at 1:16 PM

Re: Basic Security in Fusebox 5.5.x (sans XML)
I don't see anything wrong with the way you are doing it.

The extra controllers for me I see as extremely simple, and use them to group code into a ... for lack up a better word, "module". In my scenario a controller is for a module and public just happens to be one of those.

The important thing of note though is probably that while fusebox 5.5 noxml is limited in how it can accomplish some things (I actually find this to be a good thing) compared to its xml brother, there are still many ways to solve the problem.

Having a solution is really what matters in the long run, and even better if that solution is one you are comfortable with.
Posted by Matt Jones on July 9, 2008 at 10:07 AM

Re: Basic Security in Fusebox 5.5.x (sans XML)
"...primarily a data management tool ...communicate with a backend Oracle database."

You might want to have a look at what Steve Bryant is doing with his CFC called DataMgr. I just tested it out in a FB5.5 application, and it worked really nicely. Saved me quite a bit of time by not having to write all that SQL code with CFPARAMS in it. Anyway, his tool can "communicate" with Oracle, so it might be worth checking out.

DataMgr:
http://www.bryantwebconsulting.com/blog/index.cfm/2008/7/25/DataMgr-22-Beta-1
Posted by Jeff Knooren on August 8, 2008 at 7:06 AM

Name:   Required
Email:   Required your email address will not be publicly displayed.

Want to receive notifications when new comments are added? Login/Register for an account.

Time to take the Turing Test!!!

What letter comes two place(s) before the letter T? (in the alphabet, if that wasn't already apparent)
Type your answer exactly one time(s) in the designated box.

Type in the answer to the question you see above:

Your comment:

Sorry, no HTML allowed!