Start by reviewing the <cflogin> tag.
ColdFusion provides the basic framework of an authentication architecture in an easy-to-use way, but it relies upon the content of this tag to actually implement the desired scheme ... calling the <cfloginuser> tag when acceptable authentication (whatever that is to you) has been achieved.
In this tag, then, you will need to issue the appropriate LDAP queries to validate the user's credentials and to assemble a suitable list of roles for that user. Exactly how you do this is up to you... but the Internet is stuffed with examples, so don't feel like you are the first one to do this.
Depending on exactly how you have set up CF at your site, authentication can be something that the web-server checks for you before even allowing access to your site. So, "if you are here, you are authenticated." This can be very convenient, and it has become the strategy that I vastly prefer to use with intranets. It eliminates the need to implement a "login" system on your own.
I have that, but I don't know if it is right. I enabled sessionmanagement in my Application.cfm. My login page is the basic form, which goes to a login_process form which contains the <cfldap> tag (using the form variables for username and password, and than the <cflogin> tag (which also uses the form variables for username). Is there a quick way to check if the user is logged in? Thanks.
I just want to say, as politely but as forcefully as I can (while still being polite), go and review the <cflogin> tag documentation. If you have "already got that," then go back and very-carefully read the description of this tag again, along with all of the associated information in the concepts manuals.
"Logins" are not the same as "sessions" or "application variables."
ColdFusion has the means to detect that login has not yet been accomplished, and it will invoke this tag under those circumstances ... circumstances which can vary considerably, and from which this tag is designed to insulate you.
Go to the Adobe documentation section Securing Applications, take a deep breath and read this section entirely. Do not "skim it" looking for what you think you are looking for. You must understand the "big picture" of what CF is doing and why it is doing it. Particularly read About User Security and the three short sections which follow.
It's right here:
This is n-o-t intended as an "RTFM brush-off." There are many scenarios that can happen, some obvious and some not.
OK. Thanks. I shall read the whole thing.
OK. I read it. However, no matter what I put in, I cannot get the DW Login Wizard to verify with LDAP. If I hand write the <cfldap> tag, I can do a basic login (verified with #GetAuthUser()#)... I tried the same information, but it won't work... any ideas?
... any ideas?
Don't use the Dreamweaver Login in Wizard would be mine.
If you do use it, just use it to create a basic database drivien login framework, I expect that is what it is designed to do. Then tear our the DB logic and replace it with the LDAP logic.
But really this is not that complex of a code structure. It is not hard to create from hand.
I decided to get the Application.cfc, securitytest.cfm, and loginform.cfm pages from the documentation center. I just need to put in the LDAP information. The template is here:
Where would I place that code?
Where do you need to put it. There is many different places one might put this logic depending on what one is trying to secure and how one's site is organized.
Common places that one might find code like that, or references to code like that such as <cfinclude...>, <cfmodule...>, createObject() or <cfinvoke...>; would be in an Application.cfm or onSessionStart() of an Applicaiton.cfc file in the directory(ies) that one wants to secure.
Thinking about this a little while...
I would more-or-less categorically say that, if you are dealing with an application where LDAP could be used for authentication, then you are certainly dealing with an intra-net situation where the only people who can get to the web-site are already known to be "logged-on users." Presumably that login has already been handled through LDAP (nee Active Directory). So, we already know who the user is and that he is authenticated. Therefore such an app really does not need, and should not even have, its own "login" mechanism per se.
The existing (Windows) login process, therefore, has already handled authentication, and the web and/or the application server will also have handled the basic level of authorization by consenting to give the user access to the site "at all."
When the user reaches the site for the first time, ColdFusion will use its own mechanisms to realize that it does not yet know that the user is authorized (and the extent of that authorization...) for its own purposes. ("Now that he's here, what can he (not) do?") ColdFusion will magically invoke the <cflogin> tag at the appropriate time, but you really don't need to ask the user anything at this point. All you need to do is to issue an LDAP query (you already know the user's identity and his credentials have already been approved) to find out what groups he's in, to make your own determination as to the proper ColdFusion "roles." This maps the LDAP-provided information to your own business and security rules, so that the ColdFusion logic within your application can carry out the appropriate "if/then" decisions within your code.
- Users who are not logged-in to the network don't make it to your app.
- Users who aren't supposed to get to your app don't make it. either.,
- Users who do make it are already known to be who they claim to be, and you can transparently determine what choices to offer them.
- ColdFusion automagically knows when to ask you to make that determination, and provides (through "roles") a well-thought-out mechanism for implementing your decision.
TLC-IT has it pretty correct.
With a normal LDAP based system you do not have a login form. That was handled by the client operating system. You just take the information provided from that and use LDAP to retreive other information about the user, roles (groups), full name, what ever else stored in the LDAP data store your application cares to make use of.
You then uses this data in your ColdFusion application to set up the desired state data. Either something home grown using your own session variables or something with the built-in <cflogin> structure.
It is important in security though to think about what does your application really know about the user. With a normal, windows integrated security scenario, all you know is that a user logged into the system with valad credetional sometime in the recent past. That may have been hours, possible even days ago. Depending on how long users leave their system powered on, and when or if they are locked when users leave their desks. A lot of time, this is not a concern. But sometimes you want to know that the person is really the person sitting at the computer at this very second. In that scenario, you would need some type of form or something that requries immediate interataction.
Thanks for the idea, but unfortunately, that is not a feasible solution for me. The site is mixed: there are Windows machines both on and off of the domain, as well as Macs and a few Linux machines, and we cannot limit the site to just domain-based Windows boxes. This is why I need a login page, as I need ColdFusion to process all the LDAP queries and authenticate (the CF box will be on the domain). This allows for all machines to use the site, on or off the domain.
Step 1 is to run an ldap query with the user name and password. Have you successfully accomplished that?
I have the login form, which goes to a page with <cflogin> and a <cfldap> inside of it. I can run #GetAuthUser()# and return the result.
So what exactly is your problem and|or question? If you have not already figured out what you needed.
O.... OK sorry. I looked at the example from Adobe, and it used <cfif IsDefined("cflogin")> to check for login. When I run that, I get the result from the <cfelse> statement...
In addition, I can't figure out how to assign user roles based on AD/LDAP group... any ideas or staters? I need to define output by roles (Admin, Teacher, or Student). Each have their own group in the AD. Thanks!
This might be a better section of the documentation to digest.
About user security
Several pages into that you get this code sample:
In the Application.cfc onRequestStart method, or a ColdFusion page or CFC method called by the method, you have the following:
<cflogin> <cfif NOT IsDefined("cflogin")> <cfinclude template="loginform.cfm"> </cfif> <cfabort> <cfelse> <!--- Code to authenticate the user based on the cflogin.user and cflogin.password values goes here. ---> <!--- If User is authenticated, determine any roles and use a line like the following to log in the user. ---> <cfloginuser name="#cflogin.name#" Password = "#cflogin.password#" roles="#loginQuery.Roles#"> </cflogin>
A simple login form looks like the following:
<cfform name="loginform" action="#CGI.script_name#?#CGI.query_string#" method="Post"> <table> <tr> <td>user name:</td> <td><cfinput type="text" name="j_username" required="yes" message="A user name is required"></td> </tr> <tr> <td>password:</td> <td><cfinput type="password" name="j_password" required="yes" message="A password is required"></td> </tr> </table> <br> <input type="submit" value="Log In"> </cfform>
As you can see that 'cflogin' is the name of the structure that the username and password from the from was put into.
As for the AD/LDAP Group functionality. You would use the <cfldap...> tag to get the 'MEMEBERSOF" property from the active directory aka ldap data. You would then process this into the strings that you want to use to populate the "roles" property of the <cfloginuser....> tag.
OR you use it to populate your own session state variables for a home grown security model.
For translating LDAP data to User Roles, look at your data. You say teachers, students and admins all have their own groups. Run some queries for people you know to be in those groups and see what you get back. Then, if you're lucky, it's simple translation.
OK. Thanks to both of you. I will look into LDAP queries a little more. I than need to figure out how to process the users member into a string that I can use in the roles="#role#" attribute for the login.
Here's a practical example from a different world...
I once wrote a fairly restricted application which would let second-line customer-support folks look at customer orders, and which would allow their managers to do certain things and their gods to do (of course...) anything they wanted.
- The web-server used LDAP to enforce the basic rule of "you may come in." Therefore, upon arrival at my application, the user was already authenticated ("we know who you are..."), and known to be authorized at least sufficiently enough to be there at all. ("You are, at least, inside the moat.") Since an LDAP query had already been performed by the web server, known-good LDAP credentials were available and trustworthy.
- Because the entire application was "surrounded by a moat," the application did not have to be concerned with "intrusion." Since it relied upon LDAP, it needed no authentication mechanism of its own. It had no need to pose any further challenges on its own. This is much simpler, and much more secure, than the other alternatives which are typically used on the open Internet.
- LDAP allows you to define "groups" and "attributes" and to pose various (rather XPATH-like) "queries" which it will answer. Based on business rules established by the company, the app made group-membership queries to determine what a particular user could do, and set internal application variables accordingly. Throughout the application (and back-end services), appropriate tests were inserted to restrict various displays and controls to "only persons who are in this-or-that role." It is very easy and natural to express the result of those decisions in terms of "roles," as CF does (and this of course being why it does it). Hence my comment that "CF provides a very well-thought-out framework for authorization." Various things that my (non-CF...) app had to do for itself, CF will do for you. "Sweet!"
- The user did not have to do anything special: "click on the icon and go... we know who you are." The IT personnel didn't have to do anything special either, because the application, being LDAP-aware, already conformed to the user-administration console that they were accustomed to using. (Microsoft's "management console" scheme is very shrewdly designed, too.)
ColdFusion is designed with this sort of scenario in mind, and to make that scenario very easy to implement. It already takes care of the issue of knowing about "users" and "what they can do," and it also takes care of knowing when these decisions need to be made.. It provides a well-designed set of tags to let you insert your own logic ... LDAP-based or otherwise ... for use at that time.