ColdFusion 8 to ColdFusion 10 Migration: CFloginUser Not Working As Expected

After upgrading from CF8 to CF10, moving all files and databases and jumping through all the configuration hoops, the new version of the site is up and running, but the authentication/login is not working.

Here are the environments:

Old server: ColdFusion Enterprise 8,0,1,195765

Operating System: Windows Vista*

OS Version: 6.0

Update Level: .... hf801-00007.jar

IIS Version: 7

(*not sure where that "Vista" comes from? The System Information says "Windows Server 2008 Datacenter without Hyper-V")

New server: ColdFusion Enterprise 10,0,11,285437

Tomcat Version: 7.0.23.0

Operating System: Windows Server 2008 R2

OS Version: 6.1

Update Level: .... chf10000011.jar

Adobe Driver Version: 4.1 (Build 0001)

IIS Version: 7.5

I have a pretty standard ColdFusion login system, using cfloginuser in Application.cfc. After I login on the old site, outputting #GetAuthUser()# prints my username to screen, and all my role-based rules work.

On the new server, outputting GetAuthUser() prints empty.

On the old site, cfdump var="#SESSION#" includes:

cfauthorization_kllcms dXNlcm5hbWU6cGFzc3dvcmQ6YXBwX25hbWU= 

On the new site, CFDUMP of session does not show a cfauthorization_kllcms value at all. All other session values exist in both instances.

It is the exact same codebase, database structures, etc. Naturally, none of my role-based rules work, because they all depend on validation of getAuthUser() and IsUserInRole("x") conditionals.

I know the initial login process itself is working, because it is correctly setting session variables with user information, and they are available on subsequent requests. But none of the traditional cflogin data is available on subsequent calls.

Any ideas what might have changed?

UPDATE: Per Adam's suggestion (below) I set up 2 test apps, one on the old server, one on the new.

Old Server: http://cfloginold.cimhost.com/index.cfm

New Server: http://cflogin.cimhost.com/index.cfm

Use "test" and "demo982013" as user and password.

Append ?logout=true to the URL to logout and re-test. These two apps have exactly the same code, same database. I am dumping session and form values to screen, along with GetAuthUser() value.

The authentication method is pretty much exactly as outlined in Adobe's documentation, and I can share all relevant code here if necessary.

Note that in the "new" server, the form loads each time you visit the page, whether you have logged in or not. This is exemplar of the fact that the cflogin session is not being retained or recognized, thus presenting the login form each visit (although not on initial form completion, which shows that cflogin is at least working on the initial login, I think).

UPDATE 2: I've been drilling deeper into this, and I am able to get cfloginuser to fire a couple of ways, just not as part of the standard Adobe documented application-based user security model.

Option 1: I created a standalone page, and placed the following code in it:

<cflogin><cfloginuser name="directtest" Password = "2519D6025B5191F754D01BE163972628" roles="1"></cflogin>

I then instructed Application.cfc to allow this past the cflogin gate. You can see the results by pointing your browser to: http://cflogin.cimhost.com/directlogin.cfm?bypass=true

Voila. 'cfauthorization_cicmstest' value has been set, and user is logged in. Subsequent calls to GetAuthUser() are successful. So I know now that CF10 and the application do allow cfloginuser, and the user session can be created.

Option 2: I then decided maybe it was something about my Application.cfc file, so I again bypassed the cflogin gate, and placed the hard-coded cfloginuser snippet directly in my Application.cfc onRequestStart function. Logged out and visited: http://cflogin.cimhost.com/index.cfm?bypass=true&noquery=true

Again, cfauthorization_cicmstest value was successfully set, and user is logged in.

However, logging in still fails if the cfloginuser directive is fired within the actual cflogin process in Application.cfc. Here is what that code looks like:

        <cfquery name="loginQuery" dataSource="mydatasource">
        SELECT id,username, userroles
        FROM myusertable
        WHERE
           username = '#cflogin.name#'
           AND userpass = '#HASH(cflogin.password)#'
        </cfquery>
        <cfif loginQuery.userroles NEQ "">
           <cfloginuser name="#cflogin.name#" Password="#cflogin.password#" roles="#loginQuery.userroles#">
           <cfset MyMessage = "#MyMessage#<br />The Login Query fired and returned expected - loginQuery.userroles NEQ ''">

        <cfelse>
           <CFSET MyMessage = "Your login information is not valid. <a href='index.cfm?logout=1'>If your session timed out, click here!</a>">   
           <cfinclude template="loginform.cfm">
           <cfabort>
        </cfif>

I know that the query is successful, because I am setting an alert message that tells me the loginquery.userroles value was not empty, which is the condition for processing cfloginuser .

I know where the code is failing now, just not why. I've tried hard coding that cfloginuser value, and it still fails. I'm at a loss as to what to try next. The cfloginuser functionality works, just not in the one place (within the loginQuery.userroles conditional) that I need it to work.

UPDATE 3:

Just to prove to myself it wasn't my code, I created 2 more test sites, one on the old server, one on the new server:

New Server (CF10) = http://cf10loginadobe.cimhost.com/securitytest.cfm

Old Server (CF8) = http://cf8loginadobe.cimhost.com/securitytest.cfm

I copied exactly Adobe's 3 files from their Application-based security example. I created a database table with their schema and values. I added my cfdump outputs to show the sessions being created.

Test with user of "Bob" and password of "secret". Even with Adobe's own code, the tests fail on CF10.

I'm not sure what to do next. Rewriting the application to not use cfloginuser is not an option, as we have more than a dozen applications we are migrating to CF10 that use this authentication model, across hundreds of templates.

It's possible it's something weird about how IIS7.5 is handling ColdFusion requests, but that seems unlikely given the ability to successfully instantiate cfloginuser outside of the query result conditional.


ColdFusion 10 Application Based User Security Is Broken

I have deployed two test sites, using Adobe's own example code for application based user security, copied in its entirety from the Adobe website. One test site is in ColdFusion 8, one is ColdFusion 10. The code and databases are identical on both sites. I added cfdump output to monitor session variables and login status as they are set.

Test Site ColdFusion 8: http://cf8loginadobe.cimhost.com/securitytest.cfm

Test Site ColdFusion 10: http://cf10loginadobe.cimhost.com/securitytest.cfm

Logging in using a user of "Bob" and password of "secret" demonstrates the failure in CF10. Initially it appears login was successful, but note that the cfdump of the session does not show a cfauthorization_orders value in CF10, where in CF8 the value is present.

In CF8 subsequent visits to the same URL after login correctly retain the logged in user status and do not present the login form. In CF10, no session was actually created for the user, and therefore subsequent visits to the same URL prompt for login again.

I have tested this thoroughly, including bypassing the cflogin logic and forcing cfloginuser , which successfully creates an authenticated user in CF10, demonstrating that cfloginuser is supported.

It appears to me there is something about CF10's handling of the OnRequestStart function in Application.cfc that creates and then immediately kills the user session.

Workaround: The inelegant workaround I am using involves re-creating the cfloginuser session instantiation in a subsequent OnRequest function in Application.cfc. The code is as follows:

<cffunction name="onRequest">
<cfargument name = "targetPage" type="String" required=true/>
<cfinclude template=#Arguments.targetPage#>

<cfif IsDefined("loginQuery")>
  <cfif loginQuery.userroles NEQ "">
    <cflogin><cfloginuser name="#loginQuery.username#" Password = "#loginQuery.userpass#" roles="#loginQuery.userroles#"></cflogin>
  </cfif>
</cfif>

</cffunction>

If there was an attempt to login in the OnRequestStart , I leverage the results of that request, check if it was valid ( loginQuery.userroles NEQ "" ), and then instantiate the authenticated session. There is a downside in that users have to click to a new page for logged in options to appear. The GetAuthUser() test is not met until another page load is requested.

Extensive testing of alternatives within Application.cfc did not reveal any alternative to this approach.

链接地址: http://www.djcxy.com/p/60552.html

上一篇: Coldfusion中的会话

下一篇: ColdFusion 8迁移到ColdFusion 10:CFloginUser未按预期工作