I'm working on updating some apps we currently use for AD user maintenance. i.e. add new users, unlock accounts, reset passwords, etc.)
We use cgi.auth_user and then parse that to get the domain and userid of the Windows user accessing the app. We then take the user id portion of that and use that as the filter in a cfldap query. that pulls attributes we use to control access, and timestamp transactions.
That cfldap query is included in a number of pages throughout the app and I wanted to move that to either the Application.cfm file, or create a .cfc file (something we're not currently using) and put it there.
We're on ColdFusion 11, are there advantages/disadvantages to either of these methods?
Generally speaking, Application.cfc has only advantages over Application.cfm. This is because Application.cfc was designed to address the shortcomings of Application.cfm and to include further fine-grained functionality that developers need.
Thanks, was kind of thinking that was the case, but as you could probably tell, I'm fairly new to ColdFusion.
One last question, I'm planning on using the client scope for the variables created for the users AD attributes, would that be the proper scope? In addition to using those variables in the timestamp for the transactions, I'll also be using them for controlling access to pages, setting menus, etc.
The scope to use to store user-specific data that changes dynamically is session. Common examples are shopping-cart content and the boolean variable that says whether or not the user is currently logged in.
If the user-specific data is unchanged between sessions and of long-term nature, then you should store it as client variables. Common examples are date of last visit and personal site display preferences.
Thanks, I tried the session variable, but the problem I ran into was the same session variable gets set for subsequent users who log on to the app.
As an example, a user in AD group A gets a menu with a System Maintenance button in their left nav bar, but a user in AD group B doesn't see that button. By setting the AD group as session variable, the AD group of the first person who logs in sets the nav bar menu for all subsequent users regardless of their AD group.
Setting that group variable with the client scope fixed that problem, and it also prevented users in AD group B from seeing pages associated with that System Maintenance button.
What am I doing wrong here?
That sounds a bit confusing to me. It is clear from the example what happens, but I am unable to tell what you wish to happen and what you don't.
Could you please explain:
(1) the situation, what you have, for example, the groups;
(2) what you wish to achieve.
First of all, thanks for taking the time to help me with this, I really appreciate it.
(Note my syntax may be a little off here)
When the home page for this application is opened, I grab the users Windows login using cgi.auth_user. I parse all that out and use the userid as the filter in an LDAP query that pulls givenName, sn, memberof, and mail from AD.
I then set variables based on the values returned from the query. i.e. <cfset client.Group="#ldapquery.memberof#" and so on for first name, last name email, etc. In addition to using some of these variables to timestamp the transaction, i.e. client.UserID added so and so to AD on such and such date, I use the client.Group variable to select menus and control access to pages, i.e. <cfif client.Group=A> <cfinclude template="menu A"><cfelseif client.group ="B"> <cfinclude template="menuB"></cfif>.
When I do that with a session variable i.e. <cfset session.group="ldapquery.memberOf"> the first person who logs in sets the session variable for whatever their AD group happens to be, and that session variable is applied to all subsequent users who login regardless of their AD group.
First off, I hope you've chosen to use Application.cfc. I also take it for granted that, in it, you have configured the application to use session and client variables.
Your observation of the behaviour of the session variables is faulty. The ColdFusion server forbids one user from setting another's session variable. Be aware that <cfset session.group="ldapquery.memberOf"> is in all likelihood an error. You must have meant <cfset session.group="#ldapquery.memberOf#"> or <cfset session.group=ldapquery.memberOf>.
As I said earlier, the requirements should be what guide you in the choice between the client or session scope. From your description, Group is apparently a user-related property that remains unchanged across sessions. You should therefore store it in client scope.
Actually I'm using application.cfm to set session and client management, and default values for those variables. I run the ldap query and set the actual variable in a cfc.
The production app does not use application.cfm, it has a <cfapplication> tag at the top of each page, but client management was specified in the tag, so maybe that had something to do with it, more likely I just missed something the first time around.
I've got everything working with the .cfc, so let me change that client scope to session and log in with my test users, see what happens.
Oops, missed the last line of your reply.
Yes, in the case of the variables related to the user who is logged in, those variables remain constant, so therefore, you're saying I should be OK with using the client scope, correct? It does work, being kind of new to CF, I just wanted to make sure I wasn't doing anything that might jump up and bite me in the you know what on down the road.
The reason the session variable kept displaying my user info even when I was logged in with the test account, was because that test account profile got jacked up somehow. Shocker, Windows 7 User Account profile getting hosed up. Anyway, for some reason when I was logged on with the test account, the laptop still thought it was me. Guess I should have tested a little more.
Anyway I blew away the test profile on the laptop, logged back in and it's working.
Staying with the client variable for now, but everything with the application.cfm and my.cfc file is working. Thanks again for your help.
Have a great weekend.
I am glad to hear you got it to work. I would strongly advise you to switch from Aplication.cfm to Application.cfc. For a small application, you can do it in a matter of minutes. Let the forum know if you need suggestions.
Could you provide some links to documentation on that? (application.cfc versus application.cfm)
I thought the idea behind doing my client and session management, and setting some default variables in an application.cfm was that ColdFusion looks for that file each time you access a page, whereas with a component, you have to include code on each page to check for it. Like I said I'm kind of new to this.
Also, since I figured out the issue with session scope, is it best practice to use the session scope for storing these user variables, or am I OK sticking with the client scope.
Once again, many thanks for all your time and help.
I thought the idea behind doing my client and session management, and setting some default variables in an application.cfm was that ColdFusion looks for that file each time you access a page, whereas with a component, you have to include code on each page to check for it.
ColdFusion includes Application.cfc at the beginning of a page request in the same way it does Application.cfm. All you need might just be as simple as:
this.name = "myApp";
this.applicationTimeout = "#createTimespan(1,0,0,0)#";
this.clientManagement = "true";
this.clientStorage = "cookie"; /* client variables stored as cookies; so include no sensitive data in client scope */
this.sessionManagement = "true";
this.sessionTimeout = "#createTimeSpan(0,0,20,0)#";
this.setClientCookies = "true";
<cffunction name="onApplicationStart" returntype="boolean">
<cfargument name="missingMethodName" type="string">
<cfargument name="missingMethodArguments" type="struct">
<cfargument name = "targetPage" type="String" required="true">
<cfargument type="String" name = "targetTemplate" required="true"/>
<cfargument name = "SessionScope" required="yes"/>
<cfargument name = "AppScope" required="yes">
<cfargument name="Exception" required=true/>
<cfargument name = "EventName" type="String" required="true"/>
Thanks again, a lot to digest. Other things I've been reading suggest utilizing application.cfc as well so I guess I'll give it a shot.
OK, so I went ahead and created an Application.cfc, pasted the text you provided, added the methods I have in my UserAdmin.cfc and my default client variables, delete the existing Application.cfm and UserAdmin.cfc and then smoke test it?
And to confirm, I don't need a cfinvoke or other code to call the Application.cfc on each page open, just use the cfinvoke to call my methods for AD and other queries?
Wow, that didn't work at all.
Just a blank page with my default css background color. Time for lunch.
If you want, I will have a look at your Application.cfm code to see how it could be converted. Could you send it to me by private message?
Would be happy to, thanks.
Just sent it, hope I did that right.
Made the changes per your instructions, works great.
Thanks again. Great forum.
I am glad to hear. Thanks.