Active Directory Update 90%

1 view
Skip to first unread message

Chris Roth

unread,
Aug 4, 2008, 3:13:55 PM8/4/08
to farcry-beta
I am still struggling getting FC5 integrated with our MS Active
Directory. I am soo close, but I can not seem to get it there.


1. I have more or less all the default permissions set up for the
standard roles.
2. I can see my "LDAP" groups in Roles Admin. and have assigned them
to the appropriate standard Role (aka "mapping" from fc4)

3. I can even enter a AD user/pw on the LDAP Login screen with out an
error.

However...

After logging in I am returned to the "Farcry UD" login form

If I go ahead and login with e FCUD user, and go to the "user" admin
screen, I have a LDAPUD user set up in DMProfile... but there are no
"groups/roles" assigned, in fact the formtool for assigning them does
not appear (as it does whe nI edit a FCUD user).

I cant seem to figure out how to get FC to assign the Roles to the
LDAP (AD) user.

Is anyone using farcryldap? Has anyone got AD working? So close.

Once I get the Roles working, I think the only other tweak that needs
to be made is to make the login more like FC4 where it does not
require the user to "choose' the UD... I think it should look in all
the configured UDs...




Blair McKenzie

unread,
Aug 4, 2008, 8:09:40 PM8/4/08
to farcr...@googlegroups.com
I can't troubleshoot this myself, so I'll walk you through the chain of authentication functions. Hopefully we can find where the groups are getting lost.

application.security.userdirectorys[yourudkey].getUserGroups(test_user_name)
FarCry should be able to handle user groups as long as the user directory getUserGroups function is returning them correctly. Have you been able to confirm if this is the case? You can call this function directly with application.security.getUserGroups(test_user_name) from a test page. The return value should be an array.

application.security.factory.role.groupsToRoles(groups)
Groups should be a list of your groups in the form "groupname_yourudkey". It will return a list of the FarCry roles it has been able to map them to.

Let me know what results you get.

Regarding not having to select the user directory. The main reason we went this way is so that developers can create OpenID or Gmail or whatever user directories. In that situation I couldn't assume that all login forms would be compatable. That said, the division is mostly artificial - the authenticate functions of every UD are called every time the login page is requested. If you know that all your login forms are essentially the same you can
  • finese the authenticate() functions so that they don't return an error for certain authentication failures (e.g. userid doesn't exist). Remember - you can extend/override user directories the same way as content types.
  • remove the UD selector from the login form webskins (override farLogin/displayLogin)
  • return farLogin as the login form for your UD
  • and process farLogin forms in your own UD
Let me know if any of that isn't clear. Once it is I'll add it to the wiki.

Blair

Chris Roth

unread,
Aug 5, 2008, 6:02:18 PM8/5/08
to farcry-beta
Blair,

here a test.

<cfset aUsergrps =
application.security.userdirectories.LDAPUD.getUserGroups('myuser')>

<cfset lUsergrps = "">

<cfloop from="1" to="#ArrayLen(aUsergrps)#" index="i">
<cfset lUsergrps = ListAppend(lUsergrps,aUsergrps[i] & "_LDAPUD")>
</cfloop>

<cfset grp2roles =
application.security.factory.role.groupsToRoles(lUsergrps)>

<cfdump var="#aUsergrps#">

***** returns an array with my user's groups - - working...

<cfdump var="#grp2roles#">

**** Empty string

As mentioned above, I do see my AD groups listed in Roles Admin. And I
have confirmed that some of the groups output in my test code
lUsergrps, exist in the farRole_aGroups table even tho
application.security.factory.role.groupsToRoles(lUsergrps) is returing
an empty string.

---- update ---

I changed the test code to "trim" my group names and I get a UUID
returned by application.security.factory.role.groupsToRoles(lUsergrps)

<cfloop from="1" to="#ArrayLen(aUsergrps)#" index="i">
<cfset tmp = trim(aUsergrps[i])>
<cfset lUsergrps = ListAppend(lUsergrps,tmp & "_LDAPUD")>
</cfloop>

Perhaps the my problem is a leading/trailing whitespace issue?

Where is the _UDKEY get appeneded? As you can see I had to stick it
on..

Thanks a ton. Once I get this solved I'll look at your login form
recommendations.

On Aug 4, 5:09 pm, "Blair McKenzie" <shi...@gmail.com> wrote:
> I can't troubleshoot this myself, so I'll walk you through the chain of
> authentication functions. Hopefully we can find where the groups are getting
> lost.
>
> *
> application.security.userdirectorys[yourudkey].getUserGroups(test_user_name­)
> *
> FarCry should be able to handle user groups as long as the user directory
> getUserGroups function is returning them correctly. Have you been able to
> confirm if this is the case? You can call this function directly with
> application.security.getUserGroups(test_user_name) from a test page. The
> return value should be an array.
>
> *application.security.factory.role.groupsToRoles(groups)*

shi...@gmail.com

unread,
Aug 5, 2008, 8:05:10 PM8/5/08
to farcr...@googlegroups.com
User groups need to be unique within the group, but there is no
requirement for them to be globally unique - adding the UD key is how
FarCry takes care of that. In theory you could have several instances
of the same user directory with different keys.

The security.login function retrieves the user's groups, adds the UD
key, then calls groupsToRoles (among other things). In fact that code
is almost identical to yours. Sounds like whitespace is the issue -
but that would imply that the getAllGroups is returning the groups
correctly, since that is basically what is being matched against.
Strange.

Chris Roth

unread,
Aug 6, 2008, 12:48:46 PM8/6/08
to farcry-beta
OMG. After another hour this AM of WTF is wrong... I decided I'd
update the Security Cache... viola. my ldap user gets in.

Chris Roth

unread,
Aug 6, 2008, 2:48:21 PM8/6/08
to farcry-beta
Ok I have AD working, however, when I try to approve a dhtml object
(my AD user is mapped to sysadmin) I get an error:

Detail [empty string]
ErrNumber 0
Message Element METADATA.DISPLAYNAME is undefined in VARIABLES.
Resolvedname VARIABLES
StackTrace coldfusion.runtime.UndefinedElementException: Element
METADATA.DISPLAYNAME is undefined in VARIABLES. at
coldfusion.runtime.CfJspPage.resolveCanonicalName(CfJspPage.java:1682)
at coldfusion.runtime.CfJspPage._resolve(CfJspPage.java:1600) at
coldfusion.runtime.CfJspPage._resolveAndAutoscalarize(CfJspPage.java:
1735) at
coldfusion.runtime.CfJspPage._resolveAndAutoscalarize(CfJspPage.java:
1728) at
cfUserDirectory2ecfc1853033015$funcGETGROUPUSERS.runFunction(E:\Inetpub
\farcry\core\packages\security\UserDirectory.cfc:82) at
coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:418) at
coldfusion.filter.SilentFilter.invoke(SilentFilter.java:47) at
coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:
360) at coldfusion.runtime.UDFMethod
$ArgumentCollectionFilter.invoke(UDFMethod.java:324) at
coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:
56) at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:277)
at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:463) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:453) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:320) at
coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2210) at
cfsecurity2ecfc539889980$funcGETGROUPUSERS.runFunction(E:\Inetpub
\farcry\core\packages\security\security.cfc:241) at
coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:418) at
coldfusion.filter.SilentFilter.invoke(SilentFilter.java:47) at
coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:
360) at coldfusion.runtime.UDFMethod
$ArgumentCollectionFilter.invoke(UDFMethod.java:324) at
coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:
56) at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:277)
at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:463) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:453) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:320) at
coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2210) at
cfgetObjectApprovers2ecfm1885877717.runPage(E:\Inetpub\farcry\core
\packages\farcry\_workflow\getObjectApprovers.cfm:68) at
coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:192) at
coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:366) at
coldfusion.runtime.CfJspPage._emptyTag(CfJspPage.java:2644) at
cfworkflow2ecfc673826184$funcGETOBJECTAPPROVERS.runFunction(E:\Inetpub
\farcry\core\packages\farcry\workflow.cfc:61) at
coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:418) at
coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:
360) at coldfusion.runtime.UDFMethod
$ArgumentCollectionFilter.invoke(UDFMethod.java:324) at
coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:
56) at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:277)
at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:463) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:453) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:320) at
coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2210) at
cfobjectStatus2ecfm140890112._factor14(E:\Inetpub\farcry\core\tags
\navajo\objectStatus.cfm:69) at cfobjectStatus2ecfm140890112.runPage(E:
\Inetpub\farcry\core\tags\navajo\objectStatus.cfm:1) at
coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:192) at
coldfusion.filter.CFVariablesScopeFilter.invoke(CFVariablesScopeFilter.java:
63) at coldfusion.tagext.lang.ModuleTag.doStartTag(ModuleTag.java:280)
at coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2654) at
cfapprove2ecfm403145132.runPage(E:\Inetpub\farcry\core\webtop\navajo
\approve.cfm:7) at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:
192) at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:
366) at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:
65) at
coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:273)
at
coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:
48) at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:
40) at coldfusion.filter.PathFilter.invoke(PathFilter.java:86) at
coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70) at
coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:
28) at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46) at
coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38) at
coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) at
coldfusion.CfmServlet.service(CfmServlet.java:175) at
coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:
89) at jrun.servlet.FilterChain.doFilter(FilterChain.java:86) at
coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:
42) at
coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:94) at
jrun.servlet.FilterChain.service(FilterChain.java:101) at
jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106) at
jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42) at
jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:
284) at
jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:
543) at
jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:
203) at jrunx.scheduler.ThreadPool
$DownstreamMetrics.invokeRunnable(ThreadPool.java:320) at
jrunx.scheduler.ThreadPool
$ThreadThrottle.invokeRunnable(ThreadPool.java:428) at
jrunx.scheduler.ThreadPool
$UpstreamMetrics.invokeRunnable(ThreadPool.java:266) at
jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

Blair McKenzie

unread,
Aug 6, 2008, 7:27:22 PM8/6/08
to farcr...@googlegroups.com
This is occurring for two reasons:
- the default getGroupUsers function has a bug (I just fixed it :)
- it was supposed to throw an error saying "The #this.title# user directory needs to implement the getGroupUsers function". You need to override this function in your user directory. This function is basically ONLY used for the request approval process, which is why it didn't cause issues anywhere else.

Blair

Chris Roth

unread,
Aug 6, 2008, 8:14:41 PM8/6/08
to farcry-beta
Thanks Blair.

I have not gotten as far as testing my contributor/publisher, etc
permissions and functionality. the getGroupUsers() was not present in
the farcryldap plugin.

Right now I have overridden it to just return and empty array. But I
assume I will need to do something with this function shortly when I
start to get contribs and publishers working. It appears it simply
wants an array of userids, should I be trying to get my Active
Directory "publishers" userids into that array?

shi...@gmail.com

unread,
Aug 6, 2008, 8:25:55 PM8/6/08
to farcr...@googlegroups.com
That may work, but the full functionality is to return the userids for
whatever group is passed in.

The ldap plugin was written before I realised getUserGroups was
necessary, and hasn't been updated. Thanks for reminding me.

Chris Roth

unread,
Aug 7, 2008, 5:01:51 PM8/7/08
to farcry-beta
Thanks Blair.

I poked around in core and extended my ADUD with a function like this,
which seems to be working, albiet maybe not the best looking.

<cffunction name="getGroupUsers" access="public" output="false"
returntype="array" hint="Returns all the users in a specified group">
<cfargument name="group" type="string" required="true" hint="The group
to query" />

<cfset aUsers = ArrayNew(1) />

<!--- query ad for the members of a group --->
<cfldap username="#application.config.ldap.username#"
password="#application.config.ldap.password#"
server="#application.config.ldap.host#" action="query"
name="qUsers"
start="#application.config.ldap.groupstart#"
scope="subtree"
attributes="member"
filter="(&(objectcategory=group)
(cn=#arguments.group#))" />

<cfloop list="#qUsers.member#" index="i">
<cfif findnocase("CN=",i)><cfset
arrayappend(aUsers,ReplaceNoCase(i,"CN=","")) /></cfif>
</cfloop>


<cfsavecontent variable="tmpfilter">
<cfloop from="1" to="#arraylen(aUsers)#" index="i">
<cfoutput>(cn=#trim(aUsers[i])#)</cfoutput>
</cfloop>
</cfsavecontent>

<cfset userfilter = "(&(objectCategory=person)
(objectClass=user)(|#trim(tmpfilter)#))">

<!--- query AD for the userids of the CNs returned from the
members of group query--->
<cfldap username="#application.config.ldap.username#"
password="#application.config.ldap.password#"
server="#application.config.ldap.host#" action="query"
name="qUsers"
start="#application.config.ldap.userstart#"
scope="subtree"
attributes="sAMAccountName"
filter="#userfilter#" />

<cfreturn listtoarray(valuelist(qUsers.sAMAccountName))>
</cffunction>
Reply all
Reply to author
Forward
0 new messages