How to Turn on Basic Server-side Authentication for Lucee

Here’s the instructions I use whenever I need to remember how to set up basic server-side authentication on a Lucee server. These are really instructions for Apache Tomcat, which Lucee uses as its web server.

This is something I often do for development sites, but not production. It will allow your Lucee website to authenticate against a static file of users.
(If you are looking for a way to do this dynamically one option is to connect your website to Active Directory. This is how our production sites are configured and I’ve documented the process here.)

If you’re like me and migrating from Apache Webserver this process is similar to adding users to a password file using the htpasswd command.

First we will create an xml file with our user data. Store this outside of your web root! The format looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
	<role rolename="canaccessMYAPP"/>
	<user username="gaspard" password="abcd1234" roles="canaccessMYAPP"/>
</tomcat-users>

The userstore ends up being global within Tomcat, so I’ve made the security role specific to MYAPP. Later on you’ll see how I use this in the web.xml to control access to only MYAPP.

In our server.xml file, now we will tell Tomcat about our file with the user data by making an entry inside the <GlobalNamingResources> tag.

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
			  
	<Resource name="MY_APP_UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"            
               factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="C:\MY_APP-users.xml" />
  </GlobalNamingResources>

(you can remove the default user store on lines 2-6)

Now that we’ve told Tomcat about our XML file with user data, let’s tell Tomcat that this file is available within the engine.

<Engine name="Catalina" defaultHost="127.0.0.1">
      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
		<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="MY_APP_UserDatabase"/>
      </Realm>
<Host name="MY_APP.test" appBase="webapps" unpackWARs="true" autoDeploy="true" >
		<Context path="" docBase="C:\wwwroot\MY_APP\public_html\" />
		<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
		</Host>

    </Engine>

We’ve also defined our host within the <engine> area. You can read more about that here.

Now lets tell our website to authenticate against our list of users. In our web.xml we will add the following:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
id="WebApp_ID" version="3.1">
	<display-name>test</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.cfm</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.cfm</welcome-file>
	</welcome-file-list>
	<security-constraint>
		<web-resource-collection>
			<web-resource-name></web-resource-name>
			<url-pattern>/*</url-pattern>
		</web-resource-collection>
		<auth-constraint>
			<role-name>canaccessMYAPP</role-name>
		</auth-constraint>
	</security-constraint>
	<security-role>
    <role-name>canaccessMYAPP</role-name>
  </security-role>
	<login-config>
		<auth-method>BASIC</auth-method>
	</login-config>
</web-app>

As I said at the start, I usually only use this for dev environments. But if you have multiple user files for multiple web apps on one server the user accounts are global. We don’t want the users from MYAPP #1 getting access to MYAPP #2. In the above example I am controlling access by stating that this website only allows users with “canaccessMYAPP”. If I had a second user database I would make a role for those users called “canaccessOTHERAPP” and configure that web.xml to only allow the users with that role to access.

Hope some of you find this useful!

Advertisement

Migrating to Lucee from Adobe CF

I’ve been migrating a lot of older sites from old installs of Adobe Coldfusion to new servers and fresh installs of Lucee Coldfusion lately. The majority of these applications were migrated without much trouble.  I’ve found that Lucee Coldfusion is also easy to keep secure and current as it has continual stable releases and monthly patches that can be installed from the admin area.

For the most part the migration to Lucee is a simple matter of installing Lucee Coldfusion, and adding the application codebase. After thoroughly testing that the application works locally I stand up a Test server and repeat the process. After passing UAT, the test server is cloned to create the production server and the datasource is re-pointed to the production db on the new production server. Finally the DNS entry is repointed to move the web traffic from the old existing server to the new server.

Below is the process I use when starting on a new migration

  1. Stand up a Lucee dev environment
    1. I’ve been moving to Linux servers at the same time as migrating to Lucee, but for now let’s assume we’re in Windows
    2. If you’re new to Lucee, just grab the express install from Lucee.org and install it.
  2. Checkout the site’s codebase into the Lucee ROOT directory.
    1. You are using version control right?
    2. I make a new branch to track any code changes needed. If your site is simple it most likely will just work. Otherwise check this list for ideas of what might need to be changed.
    3. Alternatively you can configure it to look at a directory other than ROOT. See this blog post
    4. If you may need to set up multiple Lucee dev sites you may want to read this
    5. If you need to turn on server side authentication read this
  3. Configure any datasource your site may need in the Lucee admin area.
    1. http://YOUR_DOMAIN_NAME/lucee/admin/server.cfm
  4. While you’re in the Lucee admin area install and activate the Log Analyzer plugin.
    1. This will allow you to view the server logs much like you would in Adobe’s CFAdmin. Very handy!
  5. At this point your site may just work.
    1. If your site works, congratulations! You can begin to validate that everything really does still works
    2. If not, usually you will get an error that explains what the issue is.
    3. For more ideas of what might be wrong: Common Issues when Migrating Existing Codebases to Lucee Coldfusion.

Common Issues Migrating Existing Codebases to Lucee Coldfusion

Lately I’ve been migrating a lot of old Adobe CF sites to new Lucee installs. There’s a few differences between the two flavors of Coldfusion, but for the most part it Just Works. I’ve written the blog post below with some of the issues I’ve experienced. Hopefully this helps someone.

Have you migrated to Lucee? What issues did you find?


Does your site use Cfform Tags?

You may need to install and/or activate the Form Tag plugin through the Lucee admin area menu option  “Extensions > applications”. If you do not see this plugin available you can  download it from Lucee.org and upload it via the upload feature at the bottom of the “Extentions > applications” page.

Does your site use Cfspreadsheet?

You may need to install and/or activate the spreadsheet plugin through the Lucee admin area menu option  “Extensions > applications”. If you do not see this plugin available you can  download it from Lucee.org and upload it via the upload feature at the bottom of the “Extentions > applications” page.

Does your site generate PDFs?

The PDFs created by Lucee will be formatted differently than the ones generated by Adobe Coldfusion.  You will need to tweak the formatting to get them to work correctly.

You may need to install and/or activate the pdf plugin through the Lucee admin area menu option  “Extensions > applications”. If you do not see this plugin available you can  download it from Lucee.org and upload it via the upload feature at the bottom of the “Extentions > applications” page.

Other Issues

– Lucee Coldfusion generates JSON keys in their original case. Adobe Coldfusion generates JSON keys in uppercase. (I may have this backwards) This may be an issue if you have anything consuming JSON that is case-sensitive.

– Lucee Coldfusion does not support the Adobe Coldfusion feature called “Flash Forms”. This was a very old feature Adobe added that presented web forms using flash instead of html. Usually it is straightforward to convert these forms into normal HTML forms.

– Lucee Coldfusion does not support Coldfusion Reporting files.  I’ve only encountered this once, but it was straightforward to re-implement the report as a pdf.

– I ran into an issue where the code was dynamically generating a new Query object using the QueryNew function. Lucee’s QueryNew was counting empty list items while Adobe’s QueryNew was not.  In Coldfusion the ListLen function ignores empty list items so Lucee’s implementation seems to not follow the Coldfusion convention.

– Occasionally Lucee reveals a bug that Adobe Coldfusion allowed to pass syntax checking. I don’t have an example handy, but at the time I wondered how Adobe CF interpreted what was an obvious bug.

Creating ‘vhosts’ when setting up a Lucee dev environment

Previously when setting up a dev environment using Adobe Coldfusion I would set up multiple development sites on the same Coldfusion install using Apache vhosts. There are other ways to do this using vms or containers, but I find keeping a local dev environment as simple as possible works best for me. If the sites are all Coldfusion, I put them together in one install. (If I’m working with a different technology, then its time to set up a separate dev environment for that, just not a new environment per-site.)

Once I moved to Lucee development, I wanted to replicate the same sort of thing using Apache Tomcat. The problem I had was that Tomcat doesn’t call them “vhosts” so it took a while to Google the correct term!

The following process is how I set up multiple dev sites under one Lucee install:

Step 1)

First, we will need to edit the server.xml file.  This file is located here for me:
c:\Lucee-express\conf\server.xml
But it might also be located here: /data/lucee/tomcat/conf/server.xml
The server.xml file may be in a slightly different place for you, but its always in the conf directory.

Add the following XML inside the “<Engine>” section

<Host name="YOUR_DOMAIN_NAME" appBase="webapps"
unpackWARs="true" autoDeploy="true" >
<Context path="" docBase="PATH_TO_WEBROOT" />
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>

Step 2)

Update your hosts file with YOUR_DOMAIN_NAME so that your browser will point to your local server instead of going out to the internet.

To your hosts file, add the entry:

127.0.0.1 YOUR_DOMAIN_NAME

Step 3)

restart Lucee

Finished!

Go to your browser and type “http://YOUR_DOMAIN_NAME”  Lucee should respond with the content in the PATH_TO_WEBROOT directory.  You may need to add a port # if your install of Lucee is configured to run on something other than port 80. My environment is configured to use port 8888 so I would need to type “http://YOUR_DOMAIN_NAME:8888

How to Turn on Server-side AD Authentication for Lucee

Here’s the instructions I use whenever I need to remember how to set up server-side Active Directory authentication on a Lucee server. These are really instructions for Apache Tomcat, which Lucee uses as its web server.

Step 1)

Define a global “Realm” that contains the LDAP config info.

We will need to edit the server.xml file.  This file is located here for me:
c:\Lucee-express\conf\server.xml
But it might also be located here: /data/lucee/tomcat/conf/server.xml
The server.xml file may be in a slightly different place for you, but its always in the conf directory.

Add the following XML inside the “<Engine>” section

<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionURL="ldap://YOURSERVERNAME:PORT"
userSearch="(samAccountName={0})"
userSubtree="true"
userBase="YOURPARAMSGOHERE"
connectionName="USERNAME"
connectionPassword="PASSWORD"
/>

Your own AD creds should work for testing, but for production you should set up a service account to make this connection

Step 2)

Now that we have an LDAP Realm defined we need to tell the website to turn on basic authentication

Create an WEB-INF/web.xml file below your web root and stick all of the following XML in there:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>test</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.cfm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.cfm</welcome-file>
</welcome-file-list>
<security-constraint>
<web-resource-collection>
<web-resource-name></web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>*</role-name>
</security-role>
</web-app>

Step 3)

Restart lucee

Finished!

Now, the user will be prompted to log in to the server using their AD credentials before hitting the website. The username will be in the cgi variables if the website needs this information.

If you need to turning on LDAP logging:

Step 1)

Add
org.apache.catalina.realm.level = ALL
org.apache.catalina.realm.useParentHandlers = true
org.apache.catalina.authenticator.level = ALL
org.apache.catalina.authenticator.useParentHandlers = true

to /data/lucee/tomcat/conf/logging.properties

Step 2)

Add
debug=”99″
to the end of your Realm like this:

<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionURL="ldap://YOURSERVERNAME:PORT"
userSearch="(samAccountName={0})"
userSubtree="true"
userBase="YOURPARAMSGOHERE"
connectionName="USERNAME"
connectionPassword="PASSWORD"
debug="99"
/>

Sources

https://tomcat.apache.org/tomcat-8.0-doc/config/realm.html#JNDI_Directory_Realm_-_org.apache.catalina.realm.JNDIRealm
https://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html#JNDIRealm
http://dev-answers.blogspot.com/2010/03/enable-debugtrace-level-logging-for.html