Enable Basic Authentication in Lucee (tomcat) with Apache

h/t Mathew Olsen

I’m reposting this question here, I’m missing something. My basic authentication works for requests not getting sent to tomcat, but not working for ColdFusion pages.

What Tomcat / Lucee config file do I need to modify to either use the apache basic authentication on setup additional basic authentication?

I’m running Apache/2.4.10 (Debian) Here’s my site config file:

<VirtualHost *:80>
    ServerName dev.mysite.com
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/mysite.com/dev/docroot

    <Directory /var/www/mysite.com/dev>
      Options Indexes FollowSymLinks
      AllowOverride All
      AuthName "Secured Development Environment"
      AuthType Basic
      AuthUserFile /etc/apache2/.htpasswd
      Require valid-user
      DirectoryIndex index.cfm index.html
    </Directory>


    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Here’s what Lucee Added to my apache2.conf file

<IfModule mod_proxy.c>
    ProxyPreserveHost On
    ProxyPassMatch ^/(.+\.cf[cm])(/.*)?$ http://127.0.0.1:8888/$1$2
    ProxyPassMatch ^/(.+\.cfchart)(/.*)?$ http://127.0.0.1:8888/$1$2
    ProxyPassMatch ^/(.+\.cfml)(/.*)?$ http://127.0.0.1:8888/$1$2
    # optional mappings
    #ProxyPassMatch ^/flex2gateway/(.*)$ http://127.0.0.1:8888/flex2gateway/$1
    #ProxyPassMatch ^/messagebroker/(.*)$ http://127.0.0.1:8888/messagebroker/$1
    #ProxyPassMatch ^/flashservices/gateway(.*)$ http://127.0.0.1:8888/flashservices/gateway$1
    #ProxyPassMatch ^/openamf/gateway/(.*)$ http://127.0.0.1:8888/openamf/gateway/$1
    #ProxyPassMatch ^/rest/(.*)$ http://127.0.0.1:8888/rest/$1
    ProxyPassReverse / http://127.0.0.1:8888/
</IfModule>
1 Like

The requests are getting proxied off to Tomcat before they hit your VirtualHost. Move the <IfModule> stuff into the <VirtualHost> after the <Directory> definition. You will need to do this for each Virtual Host, so you might want to pop it into a separate file and then include in using the Include directive.

Also, try adding in:

<Limit GET POST>
    order deny,allow
    satisfy any
    deny from all
    require valid-user
</Limit>

Just after the Require valid-user line.

Still no luck.

# DEV
<VirtualHost *:80>
	ServerName dev.mysite.com

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/mysite.com/dev/docroot

	<Directory /var/www/mysite.com/dev>
  	  Options Indexes FollowSymLinks
      AllowOverride All
      AuthName "Secured Development Environment"
      AuthType Basic
      AuthUserFile /etc/apache2/.htpasswd
      Require valid-user
      <Limit GET POST>
          order deny,allow
          satisfy any
          deny from all
          require valid-user
      </Limit>
      DirectoryIndex index.cfm index.html
	</Directory>


  <IfModule mod_proxy.c>
    ProxyPreserveHost On
    ProxyPassMatch ^/(.+\.cf[cm])(/.*)?$ http://127.0.0.1:8888/$1$2
    ProxyPassMatch ^/(.+\.cfchart)(/.*)?$ http://127.0.0.1:8888/$1$2
    ProxyPassMatch ^/(.+\.cfml)(/.*)?$ http://127.0.0.1:8888/$1$2
    ProxyPassReverse / http://127.0.0.1:8888/
  </IfModule>


	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

So it is prompting you for the password but when you don’t enter it you still get the page, or is it not prompting for the password?

I get prompted for a password, hit cancel and the request to tomcat is made.

I don’t think it is, but could it be the difference between your DocumentRoot and Directory?

You could also try <Location /> instead of <Directory /var/www/mysite.com/dev>.

Also, check that mod_auth_basic is installed and loaded.

If that doesn’t work, let us know and also let us know which version of Apache 2.x you are running.

Changing Directory to Location disabled basic auth.

I’m running Server version: Apache/2.4.10 (Debian) and have auth_basic enabled in mods-enabled.

auth_basic.load -> ../mods-available/auth_basic.load

That all looks like it should work, the only thing I can think is you still have the Proxy directives somewhere else in your config included before your virtual host.

When I removed the Proxy directives the coldfusion pages don’t get processed (as expected) so it doesn’t look like there’s a directive anywhere else.

  <IfModule mod_proxy.c>
    # ProxyPreserveHost On
    # ProxyPassMatch ^/(.+\.cf[cm])(/.*)?$ http://127.0.0.1:8888/$1$2
    # ProxyPassMatch ^/(.+\.cfchart)(/.*)?$ http://127.0.0.1:8888/$1$2
    # ProxyPassMatch ^/(.+\.cfml)(/.*)?$ http://127.0.0.1:8888/$1$2
    # ProxyPassReverse / http://127.0.0.1:8888/
  </IfModule>

Thanks for all the suggestions. I’ll keep looking into this and post any resolution if I figure it out.

Got it.

Inside <IfModule mod_proxy.c> I added

     <Location />
      AuthName "Secured Dev Environment"
      AuthType Basic
      AuthUserFile /etc/apache2/.htpasswd
      Require valid-user
    </Location>

Here’s the full file

# DEV
<VirtualHost *:80>
  ServerName dev.mysite.com
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/mysite.com/dev/docroot

  <Directory /var/www/mysite.com/dev>
      Options Indexes FollowSymLinks
      AllowOverride All
      AuthName "Secured Development Environment"
      AuthType Basic
      AuthUserFile /etc/apache2/.htpasswd
      Require valid-user
      DirectoryIndex index.cfm index.html
  </Directory>

  <IfModule mod_proxy.c>
    <Location />
      AuthName "Secured Dev Environment"
      AuthType Basic
      AuthUserFile /etc/apache2/.htpasswd
      Require valid-user
    </Location>

    ProxyPreserveHost On
    ProxyPassMatch ^/(.+\.cf[cm])(/.*)?$ http://127.0.0.1:8888/$1$2
    ProxyPassMatch ^/(.+\.cfchart)(/.*)?$ http://127.0.0.1:8888/$1$2
    ProxyPassMatch ^/(.+\.cfml)(/.*)?$ http://127.0.0.1:8888/$1$2
    ProxyPassReverse / http://127.0.0.1:8888/
  </IfModule>

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Thanks again for all the help!

1 Like

Realistically you shouldn’t need to have the Auth* stuff in the Directory directive and you could dump the IfModule directive as you know that is going to be loaded, as if it isn’t loaded, then it isn’t going to work anyway.

Here’s my update config

I move <IfModule mod_proxy.c> back to my apache config

# DEV
<VirtualHost *:80>
	ServerName   dev.mysite.com
	ServerAdmin  webmaster@localhost
	DocumentRoot /var/www/mysite.com/dev/docroot

  <Location />
    AuthName "Secured Dev Environment"
    AuthType Basic
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
  </Location>

	<Directory /var/www/mysite.com/dev>
  	  Options Indexes FollowSymLinks
      AllowOverride All
      DirectoryIndex index.cfm index.html
	</Directory>

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Did you ever get this to work? I am having the same problem.

Apache 2.4.38

The request is being handed to Tomcat and skipping over Apache’s auth

according to this post you need a few extra commands

http://blog.dev-engine.net/apache-2-4-basic-auth-not-working/

AuthUserFile /etc/httpd/.htpasswd
AuthType Basic
AuthName "Password Protected Area"
Require valid-user
 
Order Allow,Deny
Deny from all
 
Satisfy Any

Thanks Zac!

Actually… After a long night and morning… the problem is “User-error!” Or, more appropriatly, admin error.

That post you cited… I have seen that, it’s wrong on a couple of levels. First, the syntax is pre Apache 2.4:

Order Allow,Deny
Deny from all

Should no longer be used though it does still work apache wants admins to stop using it. The syntax now is

Require all granted
or
Require all denied

In any case, the core problem was/is getting Apache to force authentication before proxying to Tomcat.

I first tried playing with some valves in Tomcat, that did not work. But I was at least introduced to something new by doing that!

The TL;DR solution was to use the “Location” directive properly.

I also decided to use the “Define” directive and move some common directories to a separate include conf file.

How to use the Define directive:
Define a variable called ‘listofusers’ who can access certain directories (see core - Apache HTTP Server Version 2.4)
It takes form of parameter-name parameter-value
ex: Define myVar foobar
ex: Define myVar “foobar foobar1 foobar2”


Here is a virtual host conf file that works as intended (I have tested it) with CFM/AJP, and in this example, I am also redirecting any non SSL requests to SSL.

SSLStrictSNIVHostCheck on
<VirtualHost *:443>
	
	ServerAdmin adin@www.this-site.org
	
	ServerName www.this-site.org
	
	ServerAlias this-site.org w.this-site.org ww.this-site.org wwww.this-site.org
	
	DocumentRoot /websites/this-site/www.this-site.org/web
	
	DirectoryIndex index.cfm index.html
	
	RewriteEngine On
	RewriteOptions Inherit
	RewriteCond %{HTTP_HOST} !^www\.
	RewriteRule ^(.*)$ https://www.this-site.org/ [R=301,L]
	
	SSLEngine on
	Include /etc/letsencrypt/options-ssl-apache.conf
	SSLCertificateFile /etc/letsencrypt/live/www.this-site.org/cert.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/www.this-site.org/privkey.pem
	SSLCertificateChainFile /etc/letsencrypt/live/www.this-site.org/chain.pem
	
	# Various common virtual host includes used in this CFM site
	Include /etc/apache2/my-apache-cf-ajp.conf
	Include /etc/apache2/my-apache-cf-secure-lucee.conf
	
	# Secured directories list of users and include conf
	Define listofusers "adminuser1 adminuser2 simpleuser1"
	Include /etc/apache2/my-apache-secure-directories.conf
		
	<Directory "/websites/this-site/www.this-site.org/web">
		AllowOverride None
	</Directory>
	
	CustomLog /websites/this-site/www.this-site.org/log/www.this-site.org.ssl.access.log vhost_combined
	ErrorLog /websites/this-site/www.this-site.org/log/www.this-site.org.ssl.error.log
	# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
	LogLevel error
	
</VirtualHost>

And the critical include conf where the variable “listofusers” is passed in:

Contents of “Include /etc/apache2/my-apache-secure-directories.conf”

# Any subdirectories named admin which derrick works with
<Location /admin>
	SSLRequireSSL
	AuthType Basic
	AuthName "AdminAarea"
	AuthUserFile /etc/apache2/passwords/webauth
	Require user ${listofusers}
</Location>