I am trying to get per subsystem error files in FW/1. I know the following does not work.
variables.framework = {
...
error = getSubsystem() .error',
...
UPDATE
I tried
<cffunction name="onError">
<cfargument name="Exception" type="Struct" required />
<cfargument name="Event" type="String" required />
<cfif Arguments.Exception.Type EQ 'missinginclude' >
<cfoutput>#layout('#getSubsystem()#:default',view('login/error'))#</cfoutput>
<cfreturn false />
</cfif>
<cfreturn super.onError(ArgumentCollection=Arguments) />
</cffunction>
And I get an error of:
The EXCEPTION argument passed to the onError function is not of type Struct.
If the component name is specified as a type of this argument, it is possible that either a definition file for the component cannot be found or is not accessible.
The error occurred in /Applications/ColdFusion10/cfusion/wwwroot/Pluma/Application.cfc: line 189
187 : </cffunction>
188 :
189 : <cffunction name="onError">
190 : <cfargument name="Exception" type="Struct" required />
191 : <cfargument name="Event" type="String" required />
What you can do is override the onError method in your Application.cfc to manually call the relevant per-subsystem files.
Here's an example of handling missinginclude errors with a layout in a non-default subsystem:
<cffunction name="onError">
<cfargument name="Exception" type="Struct" required />
<cfargument name="Event" type="String" required />
<cfif Arguments.Exception.Type EQ 'missinginclude' >
<cfoutput>#layout('subsys2:default',view('main:errors/404'))#</cfoutput>
<cfreturn false />
</cfif>
<cfreturn super.onError(ArgumentCollection=Arguments) />
</cffunction>
Returning super.onError will result in the standard error handling being invoked.
For making it completely per-subsystem you could do something like view(getSubsystem()&':errors') or similar.
If you're doing potentially complex logic, remember to use appropriate try/catch - tracking errors in your error handling can be awkward.
Related
I am trying to write a session helper and facing to problem to test if a Struct key in session exists?
I am trying like
<cffunction name="Exists" access="public" output="false" returntype="boolean" >
<cfargument name="Key" required="true" type="Any" />
<cfreturn Evaluate( "StructKeyExists( Session, #Arguments.Key# )" ) />
</cffunction>
Where I am calling the function like
<cfif Exists("data.fromdate") >
...
</cfif>
How should I write it?
Thanks
if you are checking to see if key "Test" exists in the session struct, try something like this:
<cffunction name="Exists" access="public" output="false" returntype="boolean" >
<cfargument name="Key" required="true" type="String" />
<cfreturn StructKeyExists(session, arguments.Key) />
</cffunction>
<cfif Exists("Test") >
....
</cfif>
Another concept, or two, since you are looking for a struct within the session would be:
<cffunction name="Exists" access="public" output="false" returntype="boolean" >
<cfargument name="Key" required="true" type="String" />
<cfreturn (structKeyExists(session, listFirst(arguments.Key,"."))
AND structKeyExists(session[listFirst(arguments.Key,".")], listLast(arguments.Key, "."))) />
</cffunction>
<cfif Exists("data.Test") >
....
</cfif>
and
<cffunction name="Exists" access="public" output="false" returntype="boolean" >
<cfargument name="struct" required="true" type="String" />
<cfargument name="Key" required="true" type="String" />
<cfreturn (structKeyExists(session, arguments.struct)
AND structKeyExists(session[arguments.struct], arguments.key)) />
</cffunction>
<cfif Exists("data", "Test") >
....
</cfif>
Hope all this helps point you in the right direction, good luck!
The following code will check any depth struct, and also correctly locks the Session scope.
<cffunction name="Exists" access="public" output="false" returntype="boolean">
<cfargument name="Key" required="true" type="string">
<cfset local.mainKeyList = ListChangeDelims(ListDeleteAt(Arguments.Key, ListLen(Arguments.Key, "."), "."), ",", ".")>
<cfset local.StructChain = "Session">
<cfloop list="#local.mainKeyList#" index="local.CurrentKey">
<cfset local.StructChain &= '["#local.CurrentKey#"]'>
</cfloop>
<cflock scope="session" type="readonly" timeout="3">
<cftry>
<cfset local.Exists = StructKeyExists(Evaluate(local.StructChain), ListLast(Arguments.Key, "."))>
<cfcatch>
<cfset local.Exists = false>
</cfcatch>
</cftry>
</cflock>
<cfreturn local.Exists>
</cffunction>
<cflock scope="session" type="exclusive" timeout="3">
<cfset Session.data.log.deep = "I'm here!">
</cflock>
<cfoutput>#Exists("data.log.deep")#</cfoutput>
Hopefully the amount of code in this function will justify why a helper function would be useful, to those pondering your reasons. This doesn't currently, but could be enhanced to, deal with Structs inside of Arrays as well. This also doesn't deal with an empty Arguments.Key, or fail gracefully on a cflock timeout, but should get you started.
Additionally, those that want to comment that cflock isn't required, please read the ColdFusion cflock docs first.
Simplified, but may provide inaccurate results in extremely rare conditions
Doing an IsDefined inline in your code will provide the opportunity for false positives, however having the IsDefined inside a udf or cfc method reduces this risk greatly to the point it may not need be a consideration. If you're happy to take that chance then you can simplify the function using IsDefined as Peter Boughton suggests.
<cffunction name="Exists" access="public" output="false" returntype="boolean">
<cfargument name="Key" required="true" type="string">
<cflock scope="session" type="readonly" timeout="3">
<cfset local.Exists = IsDefined("Session." & Arguments.Key)>
</cflock>
<cfreturn local.Exists>
</cffunction>
As Al Everett mentioned above, I don't remember the last time I had an app that didn't have session enabled. I guess if you can't be sure of that, then it makes sense to see if Session exists. My code for this would include:
<!--- in the application.cfc --->
<cffunction name="onSessionStart" output="false">
<!--- default session structure, you can also add default values to the data
structure here to ensure they exist later --->
<cfset session.data = {} />
</cffunction>
<!--- then in code use structKeyExists instead of a whole new function --->
<cfif structKeyExists(session.data, myKey)>
<!--- if you really wanted the "exists" function --->
<cffunction name="dataKeyExists" returntype="boolean" output="false">
<cfargument name="key" required="true" />
<cfreturn structKeyExists(session.data, arguments.key) />
</cffunction>
Depending on what's going on, I might choose to pass in the session to maintain encapsulation. But it doesn't always make sense to be a slave to OO and introduce complexity just for the sake of maintaining a pattern. Passing in the session structure and evaluating the key is really just a big workaround to using the "structKeyExists" function.
I also dislike having a function called "exists" because it tells me nothing about what it's really evaluating. I'd assume a function like that was like "isDefined" and more generic than just testing for a key in a specific structure.
<cfif structkeyexists(session, "data") and structkeyexists(session["data"], key)>
...
</cfif>
Why not just call <cfif isNull(session.data.fromdate)>
If the key data does not exist in session it will not throw, just returns false.
I am trying to build a web service. Here is my code for a simple web service which returns a string.
At the beginning i inserted some code from ben nadel
It refreshes the stubfile automatically because otherwise you get errors while passing parameters.
<cfcomponent
displayname="BaseWebService"
output = "false"
hint="This handles core web service features">
<cffunction
name="Init"
access="public"
returntype="any"
output="false"
hint="Returns an initialized web service instance.">
<cfreturn THIS />
</cffunction>
<cffunction
name="RebuildStubFile"
access="remote"
returntype="void"
output="false"
hint="Rebuilds the WSDL file at the given url.">
<cfargument name="Password" type="string" required="true" default="" />
<cfif NOT Compare(ARGUMENTS.Password, "sweetlegs!")>
<cfset CreateObject("java", "coldfusion.server.ServiceFactory"
).XmlRpcService.RefreshWebService(
GetPageContext().GetRequest().GetRequestUrl().Append("?wsdl").ToString()) />
</cfif>
<cfreturn />
</cffunction>
<cffunction
name="easyService"
access="remote"
returntype="any"
output="false">
<cfargument name="anyOutput" type="string" default="this and that" />
<cfargument name="xtype" type="string" required="yes" default="1" />
<cfif Compare(xtype, "1") EQ 0>
<cfset anyVar = "one" />
<cfelse>
<cfset anyVar = "two" />
</cfif>
<cfreturn anyVar>
</cffunction>
</cfcomponent>
Here I am trying to invoke the webservice.
<cfinvoke
webservice="https://[...]/Components/Webservice.cfc?wsdl"
method="RebuildStubFile">
<cfinvokeargument
name="Password"
value="sweetlegs!" />
</cfinvoke>
<cfinvoke
webservice="[...]/Components/Webservice.cfc?wsdl"
method="easyService"
returnVariable="anyVar" >
<cfinvokeargument
name="xtype"
value="2"
omit="true">
</cfinvoke>
<cfdump var="#anyVar#">
The first method of my web service component can be invoked but the second one always returns this error message:
coldfusion.xml.rpc.ServiceProxy$ServiceMethodNotFoundException: Web service operation easyService with parameters {xtype={2}} cannot be found.
at coldfusion.xml.rpc.ServiceProxy.invoke(ServiceProxy.java:149)
at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2301)
at coldfusion.tagext.lang.InvokeTag.doEndTag(InvokeTag.java:454)
If i type in the url of the webservice, by adding
?method=easyService&xtype=2
it returns the right value. but this is like passing values with a GET method.
i have been searching for hours and don't know where the problem occures.
I think when using WebService call you need to specify all arguments and use omit="true" on the proper one (not on xtype).
<cfinvoke
webservice="[...]/Components/Webservice.cfc?wsdl"
method="easyService"
returnVariable="anyVar" >
<cfinvokeargument
name="anyOutput"
value=""
omit="true">
<cfinvokeargument
name="xtype"
value="2">
</cfinvoke>
Getting something really strange that I just can't work out.
I have 3 methods within a CFC (guest.cfc):
- save
- create
- update
I pass an argumentCollection to the save method.
saveGuest = objGuest.save(argumentcollection=guestStruct)
If it includes an Identier, it passes the argumentCollecion to the update method, if it doesn't then it passes the collection to the create method.
This is working fine when called from one place int the app, but when I created a new call to the save method, the create method works fine, but if an ID is passed in the update method is called I receive an error that the UPDATE variable does not exists.
But, if I change the way I call it by creating an object of the cfc, it works..
so..
saveObject = update(argumentCollection = arguments;
Does not work. Receive an error that the update variable does not exist.
saveObject = createObject("component",'guest').update(argumentCollection = arguments);
DOES work.
note that both these calls are occuring within the guest.cfc itself.
This issue doesn't occur when I pass a form struct to the save method, but does occur when I pass it a standard struct (constructed from an XML import).
Very strange.
Anyone have any ideas on what might causing this?
EDIT 24 April - Added Code for guest.cfc
<cffunction name="save" output="false" access="remote" hint="save guest">
<cfargument name="title" type="any" required="false" default="" />
<cfargument name="first_name" type="any" required="false" default="" />
<cfargument name="surname" type="any" required="false" default="" />
<cfargument name="dob" type="any" required="false" default="NULL" />
<cfargument name="partner_first_name" type="any" required="false" default="" />
<cfargument name="partner_surname" type="any" required="false" default="" />
<cfargument name="partner_dob" type="any" required="false" default="NULL" />
<cfargument name="address_1" type="any" required="false" default="" />
<cfargument name="address_2" type="any" required="false" default="" />
<cfargument name="address_3" type="any" required="false" default="" />
<cfargument name="city" type="any" required="false" default="" />
<cfargument name="state" type="any" required="false" default="" />
<cfargument name="postcode" type="any" required="false" default="" />
<cfargument name="country" type="any" required="false" default="" />
<cfargument name="phone_bh" type="any" required="false" default="" />
<cfargument name="phone_ah" type="any" required="false" default="" />
<cfargument name="phone_mob" type="any" required="false" default="" />
<cfargument name="fax" type="any" required="false" default="" />
<cfargument name="email" type="any" required="false" default="" />
<cfargument name="business" type="any" required="false" default="" />
<cfargument name="notes" type="any" required="false" default="" />
<cfargument name="referer" type="any" required="false" default="" />
<cfargument name="prospect" type="any" required="false" default="" />
<cfargument name="occasion" type="any" required="false" default="" />
<cfargument name="occasion_date" type="any" required="false" default="NULL" />
<!---pass to Create or Save--->
<cfif NOT isdefined("arguments.guest_id") OR arguments.guest_id EQ "0">
<cfset saveObject = create(argumentCollection = arguments) />
<cfelse>
<cfset saveObject = update(argumentCollection = arguments) />
</cfif>
<cfreturn saveObject>
</cffunction>
<!---CREATE--->
<cffunction name="create" output="false" access="private" returntype="struct" hint="Create a New Item">
<cfargument name="provider_id" type="any" required="false" default="#session.providerID#" />
<cfargument name="ext_ref_id" type="any" required="false" default="NULL" />
<cfargument name="tstamp" type="any" required="false" default="#session.tStamp#" />
<cfif isValid('date',arguments.occasion_date)>
<cfset iOccasionDate = createODBCDateTime(arguments.occasion_date)>
<cfelse>
<cfset iOccasionDate = "NULL">
</cfif>
<cfset returnStruct = StructNew()>
<cfquery name="insertGuest" datasource="#Application.ds#">
INSERT INTO guest (provider_id, ext_ref_id, title, first_name, surname, full_name, partner_first_name, partner_surname, partner_full_name, address_1, address_2, address_3, city, state, postcode, country, phone_bh, phone_ah, phone_mob, fax, email, company, notes, referer, prospect, occasion, occasion_date, tstamp)
VALUES (#provider_id#, #ext_ref_id#, '#arguments.title#', '#arguments.first_name#', '#arguments.surname#', '#arguments.first_name# #arguments.surname#', '#arguments.partner_first_name#', '#arguments.partner_surname#', '#arguments.partner_first_name# #arguments.partner_surname#', '#arguments.address_1#', '#arguments.address_2#', '#arguments.address_3#', '#arguments.city#', '#arguments.state#', '#arguments.postcode#', '#arguments.country#', '#arguments.phone_bh#', '#arguments.phone_ah#', '#arguments.phone_mob#', '#arguments.fax#', '#arguments.email#', '#arguments.company#', '#arguments.notes#', '#arguments.referer#', '#arguments.prospect#', '#arguments.occasion#', #iOccasionDate#, #CreateODBCDateTime(tstamp)#)
</cfquery>
<cfquery name="guest" datasource="#Application.ds#">
SELECT max(guest_id) as id
FROM guest
WHERE provider_id = #provider_id#
</cfquery>
<cfset returnStruct.id = #guest.id#>
<cfreturn returnStruct>
</cffunction>
<!---UPDATE--->
<cffunction name="update" output="false" access="private" returntype="struct" hint="Update an existing item">
<!---general details--->
<cfquery name="update" datasource="#Application.ds#">
UPDATE guest
SET provider_id = provider_id
<cfif isdefined("arguments.title")>
,title = '#arguments.title#'
</cfif>
<cfif isdefined("arguments.first_name")>
,first_name = '#arguments.first_name#'
</cfif>
<cfif isdefined("arguments.surname")>
,surname = '#arguments.surname#'
</cfif>
<cfif isdefined("arguments.full_name")>
,full_name = '#arguments.full_name#'
</cfif>
<cfif isdefined("arguments.dob")>
,dob = #formDate2odbcDate(arguments.dob)#
</cfif>
<cfif isdefined("arguments.partner_first_name")>
,partner_first_name = '#arguments.partner_first_name#'
</cfif>
<cfif isdefined("arguments.partner_surname")>
,partner_surname = '#arguments.partner_surname#'
</cfif>
<cfif isdefined("arguments.partner_full_name")>
,partner_full_name = '#arguments.partner_full_name#'
</cfif>
<cfif isdefined("arguments.partner_dob")>
,partner_dob = #formDate2odbcDate(arguments.partner_dob)#
</cfif>
<cfif isdefined("arguments.address_1")>
,address_1 = '#arguments.address_1#'
</cfif>
<cfif isdefined("arguments.address_2")>
,address_2 = '#arguments.address_2#'
</cfif>
<cfif isdefined("arguments.address_3")>
,address_3 = '#arguments.address_3#'
</cfif>
<cfif isdefined("arguments.city")>
,city = '#arguments.city#'
</cfif>
<cfif isdefined("arguments.state")>
,state = '#arguments.state#'
</cfif>
<cfif isdefined("arguments.postcode")>
,postcode = '#arguments.postcode#'
</cfif>
<cfif isdefined("arguments.country")>
,country = '#arguments.country#'
</cfif>
<cfif isdefined("arguments.phone_bh")>
,phone_bh = '#arguments.phone_bh#'
</cfif>
<cfif isdefined("arguments.phone_ah")>
,phone_ah = '#arguments.phone_ah#'
</cfif>
<cfif isdefined("arguments.phone_mob")>
,phone_mob = '#arguments.phone_mob#'
</cfif>
<cfif isdefined("arguments.fax")>
,fax = '#arguments.fax#'
</cfif>
<cfif isdefined("arguments.email")>
,email = '#arguments.email#'
</cfif>
<cfif isdefined("arguments.subscribe_email_broadcast")>
,subscribe_email_broadcast = '#arguments.subscribe_email_broadcast#'
</cfif>
<cfif isdefined("arguments.company")>
,company = '#arguments.company#'
</cfif>
<cfif isdefined("arguments.notes")>
,notes = '#arguments.notes#'
</cfif>
<cfif isdefined("arguments.prospect")>
,prospect = '#arguments.prospect#'
</cfif>
<cfif isdefined("arguments.occasion")>
,occasion = '#arguments.occasion#'
</cfif>
<cfif isdefined("arguments.occasion_date")>
,occasion_date = #formDate2odbcDate(arguments.occasion_date)#
</cfif>
WHERE guest_id = #arguments.guest_id#
</cfquery>
<cfset returnStruct = structNew()>
<cfset returnStruct.id = arguments.guest_id>
<cfreturn returnStruct>
</cffunction>
In CF, when inside a function and you write things like <cfset iOccasionDate = ... > and <cfquery name="insertGuest" ...> you are creating these in the global variables scope of that CFC/template.
You need to write either <cfset var iOccasionDate = ... > or <cfset local.iOccasionDate = ... > or <cfquery name="local.insertGuest" ...> to ensure they are created in the local variable scope for the function, and don't overwrite other variables.
Your specific problem is because you have this:
<cfquery name="update" datasource="#Application.ds#">
So you're overwriting your update function with an update query.
A few quick things to note:
The local scope works in CF9 and above. If you're in CF8 or below you need to mimic it by writing <cfset var local = StructNew() /> at the top of your function.
If you use Railo or OpenBD there are settings to change the default behaviour to always create in local scope (which avoids the need for var/local scoping), but ACF does not have this option (yet?)
Use cfqueryparam! - Simon has already mentioned this, but it's important enough to be repeated. You should always handle data based on where it will be used - to prevent intentional and accidental injection attacks - and for cfquery that means using cfqueryparam.
It's a bit hard to be more precise without samples of the CFC code and the calling code, however I'd be inclined to suggest that you check the init() of your component. Have you got an init() method, and are you calling it? For example, outline of a component definition
<cfcomponent>
<cffunction name="init" access="public">
<cfreturn this>
</cffunction>
<cffunction name="save" access="public">
<!--- logic --->
</cffunction>
<cffunction name="create" access="public">
<!--- logic --->
</cffunction>
<cffunction name="update" access="public">
<!--- logic --->
</cffunction>
</cfcomponent>
This would then be called by either of the following
<cfscript>
// This will work in CF9 upwards
objCFC = new guest(/* add any arguments you have in the init() method here */);
objCFC.update(......);
// This also works
objCFC = CreateObject('component','guest').init(/* add any arguments you have in the init() method here */);
objCFC.update(......);
</cfscript>
edit following your example
That CFC is nasty. There are various glaring issues.
You are relying on application/session scope within the CFC thus forcing it to rely on global variables. This is what an init() method is used for among other things, as you could init(datasource, provider_id, ext_ref_id, tstamp), store those in variables. scope, and thus it will no longer be vulnerable to variables being undefined outside the CFC
You are using a LOT of VARCHAR fields with NO escaping whatsoever with a cfc with remote access permitted. This is quite vulnerable to SQL injection. Mr Bobby Tables can show you why this is bad ( http://bobby-tables.com/ )
You keep using string value NULL. If you pass this through into a database within a varchar/quotes then it will be stored as 'NULL' and not as a database NULL value
All in all, the best course of action would be to rewrite this component. The code changes on anything that uses the component will be minimal to the point of having to add in an init() and maybe removing some arguments however you will find the stability of it improved and all being well this odd issue will disappear.
I am using ColdFusion 9.1.
I am rebuilding a site from scratch and pointing an existing domain name to it. The site is still getting a few hits each day and I want to take advantage of that. I want to redirect those page requests to the home page, and not the error that is currently being served.
I am looking ONLY for a ColdFusion solution to move the bad request to the home page. So, if they request domain.com/BadPage.cfm?QString=XYZ, they will be moved to domain.com/.
I tried using the following method in the Application.cfc, but I couldn't get to work as described. It seemed to have no effect.
<cffunction name="OnError" access="public" returntype="void" output="true">
<cfargument name="Exception" type="any" required="true" /">
<cfargument name="EventName" type="string" required="false" default="" />
<cfif Exception>
<cflocation url="http://www.MyDomain.cfom/">
</cfif>
<!--- Return out. --->
<cfreturn />
</cffunction>
In short, what is the simplest ColdFusion means to redirect bad requests?
onError will not catch missing templates. Add an onMissingTemplate Handler to Application.cfc:
<cffunction name="onMissingTemplate" returntype="Boolean" output="false">
<cfargument name="templateName" required="true" type="String" />
<!--- Put your home page file name here --->
<cflocation url="/index.cfm" />
<cfreturn true />
</cffunction>
Use onMissingTemplate()
<cffunction name="onMissingTemplate">
<cfargument type="string" name="targetPage" required=true/>
<cflocation url="http://www.MyDomain.cfom/">
</cffunction>
Is there a recommended (and preferably free) way in ColdFusion to access a remote file that is protected by NTLM authentication? The cfhttp tag appears to only support Basic authentication.
This CFX Tag - CFX_HTTP5 - should do what you need. It does cost $50, but perhaps it's worth the cost? Seems like a small price to pay.
Here is some code I found in:
http://www.bpurcell.org/downloads/presentations/securing_cfapps_examples.zip
There are also examples for ldap, webservices, and more.. I'll paste 2 files here so you can have an idea, code looks like it should still work.
<cfapplication name="example2" sessionmanagement="Yes" loginStorage="Session">
<!-- Application.cfm -->
<!-- CFMX will check for authentication with each page request. -->
<cfset Request.myDomain="allaire">
<cfif isdefined("url.logout")>
<CFLOGOUT>
</cfif>
<cflogin>
<cfif not IsDefined("cflogin")>
<cfinclude template="loginform.cfm">
<cfabort>
<cfelse>
<!--Invoke NTSecurity CFC -->
<cfinvoke component = "NTSecurity" method = "authenticateAndGetGroups"
returnVariable = "userRoles" domain = "#Request.myDomain#"
userid = "#cflogin.name#" passwd = "#cflogin.password#">
<cfif userRoles NEQ "">
<cfloginuser name = "#cflogin.name#" password = "#cflogin.password#" roles="#stripSpacesfromList(userRoles)#">
<cfset session.displayroles=stripSpacesfromList(userRoles)><!--- for displaying roles only --->
<cfelse>
<cfset loginmessage="Invalid Login">
<cfinclude template="loginform.cfm">
<cfabort>
</cfif>
</cfif>
</cflogin>
<!-- strips leading & trailing spaces from the list of roles that was returned -->
<cffunction name="stripSpacesfromList">
<cfargument name="myList">
<cfset myArray=listtoarray(arguments.myList)>
<cfloop index="i" from="1" to="#arraylen(myArray)#" step="1">
<!--- <cfset myArray[i]=replace(trim(myArray[i]), " ", "_")>
out<br>--->
<cfset myArray[i]=trim(myArray[i])>
</cfloop>
<cfset newList=arrayToList(myArray)>
<cfreturn newList>
</cffunction>
This is the cfc that might be of interest to you:
<!---
This component implements methods for use for NT Authentication and Authorization.
$Log: NTSecurity.cfc,v $
Revision 1.1 2002/03/08 22:40:41 jking
Revision 1.2 2002/06/26 22:46 Brandon Purcell
component for authentication and authorization
--->
<cfcomponent name="NTSecurity" >
<!--- Authenticates the user and outputs true on success and false on failure. --->
<cffunction name="authenticateUser" access="REMOTE" output="no" static="yes" hint="Authenticates the user." returntype="boolean">
<cfargument name="userid" type="string" required="true" />
<cfargument name="passwd" type="string" required="true" />
<cfargument name="domain" type="string" required="true" />
<cftry>
<cfscript>
ntauth = createObject("java", "jrun.security.NTAuth");
ntauth.init(arguments.domain);
// authenticateUser throws an exception if it fails,
ntauth.authenticateUser(arguments.userid, arguments.passwd);
</cfscript>
<cfreturn true>
<cfcatch>
<cfreturn false>
</cfcatch>
</cftry>
</cffunction>
<!---
Authenticates the user and outputs true on success and false on failure.
--->
<cffunction access="remote" name="getUserGroups" output="false" returntype="string" hint="Gets user groups." static="yes">
<cfargument name="userid" type="string" required="true" />
<cfargument name="domain" type="string" required="true" />
<cftry>
<cfscript>
ntauth = createObject("java", "jrun.security.NTAuth");
ntauth.init(arguments.domain);
groups = ntauth.GetUserGroups(arguments.userid);
// note that groups is a java.util.list, which should be
// equiv to a CF array, but it's not right now???
groups = trim(groups.toString());
groups = mid(groups,2,len(groups)-2);
</cfscript>
<cfreturn groups>
<cfcatch>
<cflog text="Error in ntsecurity.cfc method getUserGroups - Error: #cfcatch.message#" type="Error" log="authentication" file="authentication" thread="yes" date="yes" time="yes" application="no">
<cfreturn "">
</cfcatch>
</cftry>
</cffunction>
<!---
This method combines the functionality of authenticateUser and getUserGroups.
--->
<cffunction access="remote" name="authenticateAndGetGroups" output="false" returntype="string" hint="Authenticates the user and gets user groups if it returns nothing the user is not authticated" static="yes">
<cfargument name="userid" type="string" required="true" />
<cfargument name="passwd" type="string" required="true" />
<cfargument name="domain" type="string" required="true" />
<cftry>
<cfscript>
ntauth = createObject("java", "jrun.security.NTAuth");
ntauth.init(arguments.domain);
// authenticateUser throws an exception if it fails,
// so we don't have anything specific here
ntauth.authenticateUser(arguments.userid, arguments.passwd);
groups = ntauth.GetUserGroups(arguments.userid);
// note that groups is a java.util.list, which should be
// equiv to a CF array, but it's not right now
groups = trim(groups.toString());
groups = mid(groups,2,len(groups)-2);
</cfscript>
<cfreturn groups>
<cfcatch>
<cfreturn "">
</cfcatch>
</cftry>
</cffunction>
</cfcomponent>
If the code from Brandon Purcell that uses the jrun.security.NTauth class doesn't work for you in cf9 (it didn't for me) the fix is to use the coldfusion.security.NTAuthentication class instead. Everything worked fine for me.
You could try following the guidance here: http://cfsilence.com/blog/client/index.cfm/2008/3/17/ColdFusionSharepoint-Integration--Part-1--Authenticating
Here is what it boils down to you doing:
edit the client-config.wsdd
Change
<transport
name="http"
pivot="java:org.apache.axis.transport.http.HTTPSender">
</transport>
to
<transport
name="http"
pivot="java:org.apache.axis.transport.http.CommonsHTTPSender">
</transport>
In my case I fixed this problem using 'NTLM Authorization Proxy Server'
http://www.tldp.org/HOWTO/Web-Browsing-Behind-ISA-Server-HOWTO-4.html
work fine for me :)