Skip to content

Instantly share code, notes, and snippets.

@neokoenig
Created September 18, 2011 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neokoenig/1225109 to your computer and use it in GitHub Desktop.
Save neokoenig/1225109 to your computer and use it in GitHub Desktop.
Active Directory / LDAP example in cfWheels
<--------Main.cfc----------->
<cffunction name="init">
<cfscript>
// AD Auth, application wide: if I wanted to only restrict a subset a pages, I could use 'only' instead of except below.
// This filter call should be in every controller you wish to protect
filters(through="loginRequired", except="login,dologin");
// Login
verifies(only="dologin", post=true, params="username,password", error="Both username and password are required", handler="login");
</cfscript>
</cffunction>
<cffunction name="dologin" hint="Logs in a user via LDAP">
<cfset var ldap=QueryNew("")/>
<!--- The LDAP Server to authenticate against--->
<cfset var server="ldap.server.domain.com">
<!--- The start point in the LDAP tree --->
<cfset var start="OU=People,DC=domain,DC=com">
<!--- Scope --->
<cfset var scope="subtree">
<!---- Name of group --->
<cfset var cn = "ContactsDatabaseUsers">
<cftry>
<!--- Check the user's credentials against Windows Active Directory via LDAP--->
<cfldap
server="#server#"
username="DOMAIN\#params.username#"
password="#params.password#"
action="query"
name="ldap"
start="#start#"
scope="#scope#"
attributes="*"
filter="(&(objectclass=*)(sAMAccountName=#params.username#))"/>
<!--- Get the memberOf result and look for contactsDatabase--->
<cfquery dbtype="query" name="q">
SELECT * FROM ldap WHERE name = <cfqueryparam cfsqltype="cf_sql_varchar" value="memberOf">
</cfquery>
<cfscript>
if (q.value CONTAINS "CN=#cn#")
{
params.name=params.username;
// Check for the local user profile
if( model("user").exists(where="username = '#params.username#'"))
{
// User found, copy user object to session scope
user=model("user").findOne(where="username = '#params.username#'");
user.loggedinAt=now();
user.save();
session.currentuser=user;
flashInsert(success="Welcome back!");
}
else
{
// No Local Entry, create user as LDAP Auth has been successful
user=model("user").create(username=params.username, name=params.name, loggedinAt=now());
if (NOT user.hasErrors()){
user.save();
session.currentuser=user;
flashInsert(success="Welcome - as this is the first time you've logged in, your account has been created.");
}
else
{
flashInsert(error="Error creating local account from successful Active Directory authentication");
StructClear(Session);
renderPage(action="login");
}
}
redirectTo(route="home");
}
else
{
redirectTo(route="home");
}
</cfscript>
<cfcatch type="any">
<cfscript>
if(FindNoCase("Authentication failed", CFCATCH.message)){
// Likely to be user error, e.g. typo, wrong username or password
flashInsert(error="Login Failed: please check your username and password combination");
renderPage(action="login");
}
else {
// Likely to be LDAP error, e.g. not working, wrong parameters/attributes
flashInsert(error="Login Failed: Please try again.");
renderPage(action="login");
}
</cfscript>
</cfcatch>
</cftry>
</cffunction>
</cfcomponent>
<-----------Controller.cfc------------->
<cffunction name="loginRequired" hint="This function will prevent non-logged in users from accessing specific actions">
<cfif NOT isloggedin()>
<cfset redirectTo(controller="main", action="login")>
</cfif>
</cffunction>
<cffunction name="isloggedin" hint="Checks for existence of session struct">
<cfif NOT StructKeyExists(session, "currentUser")>
<cfreturn false>
<cfelse>
<cfreturn true>
</cfif>
</cffunction>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment