Model Glue Event Security Using Broadcasts and Results

When building web applications, you will inevitably need to provide secure pages or an entire area of your application for users and administrators. For my most recent Model Glue project I wanted to define a common approach to securing all access to the admin area with the exception of login pages. After several failed attempts at universal security, I decided that securing events is best achieved through explicit broadcasts and results, with a minimal amount of logic handled within the controller. Here's a simple example.

Let's presume that the default event for my admin sub-application is "admin.home", here is my event listener declaration.

<event-handler name="admin.home">
<broadcasts>
<message name="loginRequired" />
</broadcasts>
<results>
<result name="noValidLogin" do="login.go" redirect="true" />
<result do="layout" />
</results>
<views>
<include name="content" template="home.cfm" />
</views>
</event-handler>

The loginRequired has a listener defined by the following.

<controller name="SecurityController" type="admin.controller.SecurityController">
<message-listener message="loginRequired" function="verifyLogin" />
</controller>

Finally, in my SecurityController, the verifyLogin method looks like this.

<cffunction name="verifyLogin" access="public" returnType="void" output="false">
<cfargument name="event" type="any">
<cfif not getSecurityService().adminLoggedIn()>
<cfset arguments.event.addresult("noValidLogin")>
</cfif>
</cffunction>

In a previous application I chose to use event.forward() within my controller to redirect the request to the login event. Although this works, it is, in my opinion, better to use addResult and have Model Glue handle the redirection. Although the xml is more verbose, I really like that the intent of each event is clearly defined. Which provides a nice roadmap for any other developers that may take over the project.

Comments
Dan Wilson's Gravatar I agree Paul. The way you have this structured makes it really easy to make a security review. As long as all secured events have the message configured for broadcast, then security is in place. This is way better architecture than whitelisting a set of events, or by relying on convention, or any other such magic_string methodology.

Depending on how it all worked, I might go ahead and use the event.forward.... but you are right in saying it is clearer and more easily understood by being more explicit.

DW
# Posted By Dan Wilson | 6/5/08 5:31 PM
salvatore fusto's Gravatar hi,
in the real world, you can have many types of users each with his own roles to be able to go only to some areas of the app: every event can pass an argument containing
a list of roles compatible with it, so in the onRequestStart of your login Controller you can test if the logged user has the grants required to fire that event and then
continue or rediretct to a login form or to other actions.
hope been clear
regards
salvatore
# Posted By salvatore fusto | 6/6/08 4:29 AM
Paul Marcotte's Gravatar Hi Salvatore,

I agree that using a white list as you describe is a fine design choice. My preference would be to announce the type of privileges required for the event like, "requiresAdminRights" and have the controller return results like, "noLogin" or "accessDenied" and have model glue process the re-direct.

In the end there are many ways to secure you application and it really comes down to a matter of preference.
# Posted By Paul Marcotte | 6/8/08 11:34 AM
Justice's Gravatar I am using EventGuard (http://eventguard.riaforge.org/), with some small modifications. I added the ability to add secure or public events with wildcards, so a single entry can add security to all admin.* events. I find it really easy to use, check out the config for it (single XML entry that goes in coldspring adds security for all events)

http://pastebin.com/d3222e658

Granted, EventGuard is not as evident while constructing events or looking at your event config, but its working out great for me thus far.
# Posted By Justice | 6/17/08 9:26 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.9. Contact Blog Owner