如果您也对相当健壮的解决方案感兴趣,这里有一个您可以调用的示例组件 (CFC),它还可以清除可能的注入字符。多年来,我们一直在改进它以进行身份验证,因此它经过了相当多的战斗测试。
<cfcomponent output="false">
<cffunction access="public" name="init" output="FALSE" returntype="any" hint="This is the pseudo constructor that allows us to play little object games." >
<cfset variables.ldapserver = application.yoursiteLDAP.server />
<cfset variables.ldapuser = application.yoursiteLDAP.user />
<cfset variables.ldappassword = application.yoursiteLDAP.password />
<cfset variables.ldaptimeout = application.yoursiteLDAP.timeout />
<cfset variables.ldapsecuremode = application.yoursiteLDAP.securemode />
<cfset variables.port = application.yoursiteLDAP.port />
<cfreturn This />
</cffunction>
<cffunction name="authenticate" access="public" output="false" returntype="struct" hint="">
<cfargument name="username" type="string">
<cfargument name="password" type="string">
<cfset var returnData = StructNew() />
<cfset var queryResult = QueryNew('') />
<cfset var userInfo = "" />
<cfset arguments.username = scrubStringforLDAPQuery(arguments.username) />
<cfset userInfo = retrieveUserInfo(arguments.username) />
<cfset returnData["authenticated"] = false />
<cfset returnData["detail"] = "" />
<cfset returnData["user_info"] = QueryNew("") />
<cftry>
<cfldap
action="query"
server="#variables.ldapserver#"
username="#userInfo.DN#"
password="#arguments.password#"
filter="(&(uid=#arguments.username#)(objectClass=account))"
name="queryResult"
attributes="cn,dn,uid,displayName,objectClass,uidNumber"
start="dc=yoursite,dc=subdomain,dc=domain,dc=com"
maxrows="1"
port="#variables.port#"
timeout="#variables.ldaptimeout#"
secure="#variables.ldapsecuremode#" />
<cfset returnData["authenticated"] = queryResult.RecordCount EQ 1 />
<cfset returnData["user_info"] = queryResult />
<cfcatch>
<cfif FindNoCase("Invalid Credentials",cfcatch.Message) LTE 0>
<cfrethrow />
</cfif>
<cfset returnData["detail"] = cfcatch.Message />
</cfcatch>
</cftry>
<cfreturn returnData />
</cffunction>
<cffunction name="retrieveUserInfo" access="public" output="false" returntype="query" hint="">
<cfargument name="username" type="string">
<cfset var queryResult = QueryNew('') />
<cfset arguments.username = scrubStringforLDAPQuery(arguments.username) />
<cfldap
action="query"
server="#variables.ldapserver#"
username="#variables.ldapuser#"
password="#variables.ldappassword#"
filter="(&(uid=#arguments.username#)(objectClass=account))"
name="queryResult"
attributes="cn,dn,uid,displayName,objectClass,uidNumber,shadowExpire,gecos,homeDirectory,loginShell"
start="dc=yoursite,dc=subdomain,dc=domain,dc=com"
maxrows="10"
port="#variables.port#"
timeout="#variables.ldaptimeout#"
secure="#variables.ldapsecuremode#" />
<cfif queryResult.RecordCount GT 1>
<cfthrow message="More than 1 user found in LDAP" detail="More than 1 user matched uid=#arguments.username#" />
</cfif>
<cfreturn queryResult />
</cffunction>
<cffunction name="retrieveGroupInfo" access="public" output="false" returntype="query" hint="">
<cfargument name="groupname" type="string">
<cfset var queryResult = QueryNew('') />
<cfset arguments.groupname = scrubStringforLDAPQuery(arguments.groupname) />
<cfldap
action="query"
server="#variables.ldapserver#"
username="#variables.ldapuser#"
password="#variables.ldappassword#"
filter="(&(cn=#arguments.groupname#)(objectClass=posixGroup))"
name="queryResult"
attributes="cn,dn,objectClass"
start="dc=yoursite,dc=subdomain,dc=domain,dc=com"
maxrows="10"
port="#variables.port#"
timeout="#variables.ldaptimeout#"
secure="#variables.ldapsecuremode#" />
<cfif queryResult.RecordCount GT 1>
<cfthrow message="More than 1 group found in LDAP" detail="More than 1 group matched uid=#arguments.groupname#" />
</cfif>
<cfreturn queryResult />
</cffunction>
<cffunction name="scrubStringforLDAPQuery" access="public" output="false" returntype="string" hint="Removes offensive characters from string for use in an LDAP query">
<cfargument name="stringToScrub" type="string">
<cfargument name="blockWildcard" type="boolean" default="false">
<cfset replaceCharacterList = ";=" />
<cfif arguments.blockWildcard>
<cfset replaceCharacterList &= "*" />
</cfif>
<cfset arguments.stringToScrub = REReplace(arguments.stringToScrub,"[#replaceCharacterList#]","","all") />
<cfreturn arguments.stringToScrub />
</cffunction>
</cfcomponent>