Extremely Simple CFML Authentication Example?


#1

Good afternoon,

I’m curious if anybody has some drop-dead simple, uncomplicated, extremely amazingly uncomplex simple examples of setting up a extremely simple directory authentication system in CFML. Did I say simple?

I’ve tried to use the simplest example that I can find, which is the one in the Adobe docs, and it does not work. I get a “Authentication data is missing,” which is commented in the source with, “This code should never run.” (Spoiler: That code runs.) I have no idea if this is an ACF/Lucee compatibility issue.

I’ve looked around at a variety of examples and everything is just unbelievably complex and completely, totally impenetrable for me. I am growing convinced that there actually are not any simple, functioning examples of simple directory authentication in the entire Lucee/CFML universe. Like, literally none.

If anybody has any insight into a simple, drop-dead simple, extremely wildly incredibly amazingly stupendously SIMPLE example that I can at least get started with, I would be most appreciative.

A tutorial, a code example, a Stack Overflow page … anything. And trust me. I’ve looked. EVERYWHERE.

All I need is a login form for one user (me) to protect a directory (without using Basic Authentication through the web server). That’s it.

Thank you!


#2

The reason you find no simple examples, well… except for that blasphemous code Adobe still has lying around… is that proper security requires more complex handling.

I will first refer you to https://cfdocs.org/security, where if you scroll down you’ll find two topics… authentication and sesssion management. That’s about as drop dead simple as secure auth gets, really.

Much of that example code (and more) is implemented in https://github.com/ddspringle/framework-one-secure-auth which could be a jumping off point for a secure authentication system.

That said, there are insecure ways to implement protecting your cfm files. You didn’t really elaborate on what ‘directory’ means… if you mean protecting cfm file within that directory from being executed without logging in, then there are several insecure ways to handle this.

First, your login form can process your login using static user/pass. If you enter the proper user/pass, as defined and compared against in the login processing code, then you get access. For example:

if( form.username eq 'alice' && form.password eq 'bob' ) {
   /// they have access, set some session var or cookie
   session.isLoggedIn = true;
   // OR
   cookie.isLoggedIn = true
}

For session management, if could be as simple as putting the following in onRequestStart() in your Application.cfc in the directory you wish to protect:

// check that the isLoggedIn session var exists, and is true
if( !structKeyExists( session, 'isLoggedIn' ) || !session.isLoggedIn ) {
   // it does not or it is not, force a login
   location( 'login.cfm', false );
}

OR

// check that the isLoggedIn cookie exists and is true
if( !structKeyExists( cookie, 'isLoggedIn' ) || !cookie.isLookedIn ) {
   // it does not or it is not, force alogin
   location( 'login.cfm', false );
}

This is entirely insecure and would be easily hackable. But, if you’re ok with that risk, then the above combination of poor techniques will get you going in the right direction.

That said, I implore you to read the security guide’s auth and session management tutorials, and look over the relevant code in the fw/1 example, to better understand how to go from this insecure solution to the layered approach demonstrated in those places.

If you mean actually protecting a directory of files of any type, then you’re looking at either Basic Auth or NTLM (Windows) auth depending on if you’re serving over Apache or IIS. NTLM auth requires you to auth with a user either in AD or on the system itself (depending on how you configure it) and there are tons of articles on how to do this online already so I won’t go into the gory details here. Both of those have their drawbacks as well and neither is considered very secure.

There is also the <cflogin> and <cfloginuser> stuff which I don’t personally use and cannot speak to, but more blasphemous Adobe code on this can be found https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-tags/tags-j-l/cflogin.html.

HTH

Denny


#3

Thank you, Denny.

I will take a look at those documents at cfdocs again, but when I ran across them in my earlier research, I found them – well – not simple. I don’t know anything about cfscript, and there were no complete examples – just a bunch of snippets and no idea whether they should be in cfscript tags or script tags, what their inter-relationship is … what the heck “cryptoJS” is… what snippets go on what pages … those documents put me at a total loss. Overwhelmed, confused, etc.

Since I am dumb, I was interested in the cflogin tags, but, again – no good working examples to help guide me.

Also, I looked into the fw/1 package and again nothing at all straightforward about that. I searched the entire wiki for “login” and got nothing. It was even less understandable than the cfdocs stuff.

As for my requirements – I just need to limit execution of .cfm pages in a particular directory to just myself.

Sorry for excessively dramatic expressions of exasperation. I have been able to learn so, so much about CFML since I started back in 2003 – all on my own from brilliant and simple tutorials all over the internet and from smart, helpful teachers who take the time to explain things and provide extensive, simple examples and documentation in forums, stack overflow, help files, and more.

This kind of help simply does not seem to exist in any kind of similar form when it comes to authentication and security. Like … at all. That’s why I’m struggling.

Thanks


#4

I wrote the security guide at cfdocs, so your observations and criticism of them are welcomed. You make some valid points and I will use your advice to improve the documentation. Thank you for that!

The fw/1 secure auth example application ties together all the concepts outlined in the docs… but as you’ve pointed out there is still a disconnect between them. Given your lack of exposure to script I can understand how you might have gotten lost looking at it.

I don’t write in tags anymore, so all of my examples are going to be in script format, I’m afraid. I would be remiss if I didn’t suggest you learn scripting instead of using tags. Resources include:

As for auth and security, yes there is a dearth of copy and paste examples of this online. It is a complex subject with multiple possible solutions - some more secure than others - so distilling it down into something everyone can consume is difficult, as evidenced by your own observations of my attempt to do so. While the patterns can be easily duplicated once you understand them, building a solution that works for all situations ala copy & paste style would be nigh impossible. There’s a lot of moving pieces you need to understand to do it right.

All that said, in my prior example… the first block of code I posted would go wherever you process your login form (wherever your form POSTs to).

The second or third block would go into the onRequestStart() function inside your Application.cfc. If you’re not using Application.cfc (but instead using Application.cfm) then you’d be better off converting it to an Application.cfc. Resources include:

If you still can’t make heads or tails out of any of this, then I would suggest you hire a developer to either a) create the solution you need for you and/or b) train you to do it yourself. Resources include:

HTH

– Denny


#5

Thank you Denny for the link to https://cfdocs.org/script, I don’t think I’ve ever seen that before.

I wonder if documentation should have some kind of tracking so that you could see if you’ve ever been to a page or not. Or ask the documentation to show you something new - hopefully sorted by most popular features first.

That way you can assured that you’ve at least seen the most relevant things.
Instead of just displaying the page, have some kind of interaction with the learner.


#6

https://github.com/foundeo/cfdocs/ is open source, so any features you think it should have can be easily added and submitted as a merge request.

That said, it’s also databaseless - everything runs on .json - so tracking individual user usage would be difficult. I suppose you could use a cookie to store ‘pages visited’ perhaps (though even that might get to be too much data for a cookie at some point given the # of pages).

That said, a ‘surprise me’ ala Google Search style might be feasible… though again it might end up showing you something you’ve already seen w/o some form of tracking.

If you do come up with some method to do those though, I’m sure Pete would be happy to give a merge request a look. If you don’t have time to do it yourself, then it might be something you could add as a feature request on GitHub and someone else might take it up.

And glad you got to see something new from my comments. I always check cfdocs.org first before I go anywhere else… there’s a lot of excellent information there - both in the tag/function pages and in the guides!

– Denny