cflogin or home brew security
April 29, 2008
I've always used my own "home brew" version of security for my web applications instead of the native cflogin functionality, mainly due to the fact that prior to version 8 of ColdFusion, you only had the restrictive IsUserInRole() function.
The trouble with IsUserInRole() is that if you passed it a list of roles, it would check that the user had all of them. This is very frustrating if you had a page that you wanted the roles "CEO, Cleaner and Accounts" to be able to access. Obviously each of those would have totally different premissions. The way round this was to loop through you list checking permissions one at a time until you got a positive result.
ColdFusion 8 introduces the IsUserInAnyRole() function, which solves the issue I've just outlined above. ColdFusision 8 also has the IsUserLoggedIn(). Great I thought, time to use cflogin in my applications.
Unfortunately it didn't take long before I had met the first brick wall. I am building an application that allows the site owner to set passwords for specific areas of their website. If a visitor tries to access a restricted page then they are required to login. This works fine with cflogin. The problem arises when they then try to access another restricted area which has a different password. If I run the cfloginuser tag again then the initial permissions are lost. There is no way to assign more permissions to the visitor without using the cfloginuser tag.
The solution? I've gone back to my own security model, which includes a function to add roles to a logged in user.
- Posted in:
- ColdFusion
8 comments
Leave a comment
If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

I also set my security at folders and not "actions / methods" so I have this
<cfset APPLICATION.myApp.objects.security.restrictPath("configuracion/usuarios/", "admin")>
The path and the role, the code is
<cfif CGI.PATH_INFO CONTAINS ARGUMENTS.path AND NOT IsUserInAnyRole(ARGUMENTS.roles)>
<!--- Do what you want here because they are not allowed --->
</cfif>
Comment by Raul Riera – April 29, 2008
Maybe it is just my faulty understanding of the tags but I am having to do a combination of the cflogin and setting session values for the userid .
Comment by Michael Brennan-White – April 29, 2008
How would you solve my problem where the site administrator can create pages and set individual usernames and passwords for each one?
As the visitor could potential have separate login details for page x and page y, if I use cflogin then when they login for page y, they would no longer have access to page x without logging in again (and thus logging them out of page y!).
Equally my system allows the same username and password for multiple pages so the visitor only has to login once to access those pages.
@Michael,
I'm with you on that one. I have had to use a session struct and cflogin if I want to be able to store more information (such as username, user id, alias, colour scheme etc as well as permissions)
Comment by John Whish – April 29, 2008
Comment by John Whish – April 29, 2008
Comment by Dan Vega – April 29, 2008
Having a different username/password for different pages within the same application is probably not really what cflogin was designed for. If you were using role-based security with cflogin you would have your client assign roles to the pages instead of user/pass, then if a user had the correct role, they could access the page. This would, of course, also fix the issue of users needing more than one password for the same site.
That said, if you NEED to have multiple passwords within the same site, you might want to look at making each page into its own Application with its own Application.cfc, probably one that extends a Base Application.cfc so that you are not having to reproduce all your application settings. Then you can give each application its own name and hence (I think) its own cflogin space.
I have only briefly tested using a different Application.cfm for each page, of course each page needed to be in it's own folder. But it seemed to work for me. I'll be curious to hear what you think.
@Michael and John
It is very common, and most time required, to use a session struct along with cflogin to capture more information about the users and their sessions. cflogin just doesn't store enough info. One perfect example is that I usually need to store a session.userid so that I can pass it into onSessionEnd to log the user out when they don't hit the Logout button. But I agree with you both, it would be nice to have a cflogin scope that could contain my authentication structs. But then again, that may be redundent since I can do it quite easily in the session scope.
Comment by Jason Dean – April 29, 2008
In that case you are right, it wouldnt be possible to do so unless you change that admin to create "roles" for those pages instead of usernames and password (which could be simpler to do) and then assign those roles to the users.
But then again, you cheated and came before CF 7 :P so your own security system would be fine I guess, because you will be "making a totally new one" if you switch to cflogin
Comment by Raul Riera – April 29, 2008
It's always great to get fellow developers perspectives on these things.
I did actually think of a way of solving the problem I described using cflogin, but it is a bit of a hack.
If you store the user's current roles in a variable before you run the cflogin again (with a different username and pasword), you can then add the original roles to the new roles in the cfloginuser tag.
Something like this...
<cfset existingroles = GetUserRoles() />
<cflogin>
...
<cfloginuser
name = "name"
password = "password"
roles = "#existingroles#,#ValueList(qSecurity.role_id)#">
</cflogin>
The system I'm building is a CMS, so one script represents all pages that the client creates (content is a database). The client wants to be able to set usernames and passwords for each 'virtual' page so that they can restrict different pages for different users. However (and this is where my problem lies), the client may also give one user, multiple usernames and passwords to access different pages. (Crazy I know but they didn't want to pay for a proper user based security admin system where they could assign 'pages' to different users).
I guess the point that Michael raises is that you end up having user information stored in two different scopes (cflogin and the session). When you can just use your own session scope to store the authentication with a home brew security system this seems messy as the two scopes aren't associated. It gets even worse it you decide to use loginStorage = "cookie"!
Comment by John Whish – April 30, 2008