Windows Authentication

I’m adding Windows Authentication to an existing app and can’t get it to work.

There’s a complete test environment with AD setup on a Windows 2019 Server and a separate IIS 10 server connected to the windows domain. Windows Authentication is turned on in IIS.

The browser (I’m using Edge) correctly prompts the user to log on when the website is accessed. I enter a valid (domain) username and password, which the browser accepts.

The only way I know of to get the username, which was entered into the browser prompt, is to use CFLOGIN. In Application.cfc, onRequestStart was modified. CFLOGIN is supposed to be defined at this point and CFLOGIN.Name should contain the username.

This fails because CFLOGIN is undefined.

What am I doing wrong? Has anyone gotten CFLOGIN to work using Windows Authentication.

Thanks,
Mike

A couple of things I’ve tried, which haven’t worked, are.

  1. I setup Lucee to run under a Domain account.

  2. Changed the security for the web folder (from which CFM and HTML files are served) so that all Domain Users have Read access.

I have never used cflogin, because I code all my login procedures way before cflogin existed. And I also haven’t used windows auth. So I’m not sure if this is really being a little helpful. But…

From reading your post I think you are supposing that cflogin will do all the Window Auth stuff automagically for you (e.g. setting the username). I think that’s not the case. Cflogin just gives a set of functionality that should make coding using username, roles and stuff a little easier. But because cflogin was introduced very late in cfml history, many cfml developers have their own approach/alternative of coding access management.

From reading docs about IIS/Tomcat and Windows Auth, you should have additional cgi variables supplied by IIS to your Tomcat instance through AJP (cgi.auth_user/cgi.remote_user). These would be the first variables I’d check to see if they are being supplied.

ADS works under ldap. Bind a simple ADS relay (ADS LITE) or an ldap server to your ad network.

The following code will give you an idea what you need to do

<cfparam name="isAuthenticated" default="false">  
<cfparam name="logindomain" default="domain">  
<cfparam name="ldapServer" default="10.0.0.10">  
<cfparam name="adsbindie" default="DC=mydomain,DC=us,DC=com">    
<cfif IsDefined("form.username") AND form.username is not "" AND IsDefined("form.password") AND form.password is not "">      
   <cftry>          
         <cfldap action="QUERY"          
               name="auth"          
               attributes="samAccountName"          
               start="#dcStart#"          
               scope="SUBTREE"          
               maxrows="1"          
               server="#ldapServer#"          
               username="#logindomain#\#form.username#"          
               password="#form.password#">          
         <cfset isAuthenticated="true">             
      <cfcatch type="ANY">              
         <cfset isAuthenticated="no">          
      </cfcatch>      
   </cftry>  
</cfif>    
<cfoutput>      
   <cfif isAuthenticated>          
      <p>You are authenticated: #isauthenticated#      
   <cfelse>          
      <p> Sorry, I can't do that Dave    
   </cfif>      
<form action="#cgi.script_name#" method="POST">      
   <p>Enter a your username and password to see if you can authenticate       
   <p>Username #logindomain#\<input type="Text" name="username" <cfif (IsDefined("form.username") AND form.username is not "")>value="#form.username#"</cfif>>      
   <br>password<input type="password" name="password" <cfif (IsDefined("form.password") AND form.password is not "")>value="#form.password#"</cfif>>      
   <br><input type="Submit" value="Login" name="">      
</form>  
</cfoutput>

On difference I noticed between the Adobe and Lucee documentation for CFLOGIN is that there is an extra attribute in the Adobe version. The attribute is UseBasicAuth=TRUE|FALSE. I tried this with Lucee and receive an error that the attribute is not allowed.

I think this may resolve the issue by setting UseBasicAuth=FALSE. It will force NTML or Kerberos to be used.

Mike

Thanks. CFLDAP will be my fallback.

The nice thing about CFLOGIN is that the application never gains access to the password. The authentication is done behind the scenes. By the time CFLOGIN is encountered, the user has already been authenticated (via a negotiation between browser and Active Directory).

Mike

If you have correctly enabled Windows Authentication in IIS (as indicated above) then, if the client is using Chrome, Edge or IE browser and they are in the same domain as the web server then, Lucee will see the variable cgi.auth_user containing their windows credentials in the format domain\sAMAccountName. That is it. It is then up to you in your code to determine what to do with that variable, setting permissions and access. There is no requirement for a login page as the user has already authenticated in cgi.auth_user. If they use Firefox then they will be prompted by the browser to enter credentials, however, the format of username will not be obvious to the user.

If the web site is on an internal Intranet and all staff use Chrome, Edge or IE browser then Windows Authentication is OK. However, if not then a better solution to using Windows Authentication is to have anonymous authentication and a login page and when they enter their username and password use their details with CFLDAP to look up Active Directory. If they enter an invalid username or password then Active Directory will return an error code. Once they have authenticated then set a session variable or two that is tested on every other page on the web site and if that session variable is not set then redirect them to the login page. This method will work with Firefox and on Internet facing web sites. Better again is adding multi-factor-authentication.

1 Like

Thanks for the responses.

I used CGI.auth_user and it works well. If the variable exists and is not empty, the app assumes windows authentication. Otherwise it falls back to form based authentication.

And the nice think about using the variable, as opposed to CFLOGIN, is that we can continue to manage the users (and sessions) ourselves. Although, it is unclear what to do when the session expires (along with session variables) with window authentication. We’ll experiment a bit I guess.

Mike

1 Like